﻿/*
____
 L|ypps Web controls for ASP.NET

Copyright (c) 2009 Alessandro Zifiglio, http://www.Typps.com
EMail: alessandro@Typps.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
namespace Typps
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Design;
    using System.Globalization;
    using System.IO;
    using System.Resources;
    using System.Text;
    using System.Web;
    using System.Web.Hosting;
    using System.Web.Script.Serialization;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Xml;

    using Wilco.CodeHilighter.Engine.SyntaxHighlighting;

    /// <summary>
    /// Summary description for Editor
    /// </summary>
    [ToolboxBitmap(typeof(ResourceDummy), "Typps.Resources.Images.editor.bmp")]
    [DefaultProperty("Text")]
    [DesignerAttribute(typeof(Typps.EditorDesigner))]
    [ToolboxData("<{0}:Editor runat=\"server\"></{0}:Editor>")]
    [ValidationPropertyAttribute("Text")]
    public class Editor : ControlBase
    {
        #region Fields

        private ClientScriptManager cs;
        private string _codeHilightText = string.Empty;
        string _colorPickerSkinFolder = "Typps.Resources.Skins.{0}.Images.ColorPicker.{1}";
        string[] _cssClassIdentifiers;
        private CssClassNameCollection _cssClassNamesList = null;
        string _cssKey = "Typps.Editor";
        private Dictionary<string, string> _defaultItems = new Dictionary<string, string>();
        private DictionaryCollection _dictionaries = null;
        private bool _displaySpellingCompleteMessage = true;
        private List<ElementPair> _elementsAllowed = null;
        private ColorPicker _embeddedColorPicker;
        private ImagePicker _embeddedImagePicker;
        private UpdatePanelProgress _embeddedUpdatePanelProgress;
        private bool _enumerateFileGallery = false;
        HTreeNode _fileGalleryNode;
        private string _ignoredWords = string.Empty;
        private List<string> _importantClasses;
        string _keyFormat = "Editor_{0}";
        private StringBuilder _replacedText = new StringBuilder();
        string _rootImageSkinFolder = "Typps.Resources.Skins.{0}.Images.Editor.{1}";
        string _rootSkinFolder = "Typps.Resources.Skins.{0}.{1}";
        string _rootTemplateSkinFolder = "Typps.Resources.Skins.{0}.Templates.{1}";
        string _styleSheetName = "Css.editor.css";
        private HtmlGenericControl _tabContainer = null;
        private Unit _tabContainerWidth = Unit.Empty;
        private HtmlGenericControl _tabList = null;
        private TabCollection _tabs = null;
        string _tabsImageSkinFolder = "Typps.Resources.Skins.{0}.Images.Editor.Tabs.{1}";
        TextBoxNoEncode _textBoxHtmlContainer;
        private ToolBarCollection _toolBars = null;
        string _toolBarSetImageSkinFolder = "Typps.Resources.Skins.{0}.Images.Editor.ToolBarSet.{1}";
        string _toolBarsImageSkinFolder = "Typps.Resources.Skins.{0}.Images.Editor.ToolBars.{1}";
        private string _validationMarkup = string.Empty;
        private string _webResponseData = string.Empty;
        private string _wordCleanupMarkup = string.Empty;
        string _wordForSuggestion;

        #endregion Fields

        #region Constructors

        public Editor()
            : base("ul")
        {
        }

        #endregion Constructors

        #region Events

        public event EventHandler BrowseFilesServerRequest;

        public event UploadedFileEventHandler FileUploaded;

        /// <summary>
        /// This event handler fires when the MaxLength property is set and when the Editor contains more than the max text value. 
        /// This happens when the editor renders in downlevel mode, allowing you to to take appropriate action.
        /// </summary>
        public event TextChangedEventHandler MaxLengthReached;

        public event UploadedMultiFileEventHandler MultiFilesUploaded;

        public event TextSavingEventHandler SaveClick;

        public event EventHandler SelectedDictionary;

        public event TextChangedEventHandler TextChanged;

        #endregion Events

        #region Properties

        /// <summary>
        /// Gets a value indicating whether the page request is the result to a client callback made by 
        /// Typps
        /// </summary>
        [Browsable(false)]
        public static bool IsAsyncCallBack
        {
            get
            {
                if (HttpContext.Current == null || HttpContext.Current.Request == null) return false;
                string key = "iscallback$Typps";
                string value = HttpContext.Current.Request.Form[key];
                return (!string.IsNullOrEmpty(value));
            }
        }

        /// <summary>
        /// Gets a value indicating whether the page request is the result to a client callback made by 
        /// Typps for HTML View
        /// </summary>
        [Browsable(false)]
        public static bool IsCallBackForHtmlView
        {
            get
            {
                if (HttpContext.Current == null || HttpContext.Current.Request == null) return false;
                string key = "iscallback$htmlview$Typps";
                string value = HttpContext.Current.Request.Form[key];
                return (!string.IsNullOrEmpty(value));
            }
        }

        /// <summary>
        /// Gets a value indicating whether the page request is the result to a client callback made by 
        /// Typps when the save button is clicked. Please note that a SaveClick event is 
        /// already exposed by the editor in case your real intention was to listen for the save operation.
        /// </summary>
        [Browsable(false)]
        public static bool IsCallBackForSave
        {
            get
            {
                if (HttpContext.Current == null || HttpContext.Current.Request == null) return false;
                string key = "iscallback$save$Typps";
                string value = HttpContext.Current.Request.Form[key];
                return (!string.IsNullOrEmpty(value));
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating whether the editor should clean up ms specific markup automatically
        /// </summary>
        [DefaultValue(true)]
        public bool AutoCleanupMSWordMarkup
        {
            get
            {
                return (ViewState["AutoCleanupMSWordMarkup"] == null) ?
                    true : (bool)ViewState["AutoCleanupMSWordMarkup"];
            }
            set { ViewState["AutoCleanupMSWordMarkup"] = value; }
        }

        /// <summary>
        /// When true, a dialog for uploading files that still hold references to files on 
        /// the local file system will be displayed automatically upon switch from 
        /// designview to htmlview and viceversa. 
        /// Once uploaded the file, the original element holding
        /// the file reference is updated with the new file path.
        /// This will require that you subscribe to an event handler that provides a listing
        /// of the new uploaded files path, after the upload has occurred.
        /// </summary>
        [DefaultValue(true)]
        public bool AutoPromptMultiFileUpload
        {
            get
            {
                object o = (object)ViewState["AutoPromptMultiFileUpload"];
                return (o == null) ? true : (bool)o;
            }
            set { ViewState["AutoPromptMultiFileUpload"] = value; }
        }

        /// <summary>
        /// This is an IE only setting that stops your paths provided in anchor elements href attribute
        /// and image elements src from getting automatically resolved to the absolute url.
        /// The default is false, this means any attempts by IE to change a url you provided
        /// will not happen and your urls remain untouched as you intended it to. If you would
        /// rather the default behavior then set this value to true. 
        /// This is really a fix for unwanted behavior with the default setting of false.
        /// </summary>
        [DefaultValue(false)]
        public bool AutoResolveToAbsolutePath
        {
            get
            {
                return (bool)(ViewState["AutoResolveToAbsolutePath"] ?? false);
            }
            set
            {
                ViewState["AutoResolveToAbsolutePath"] = value;
            }
        }

        /// <summary>
        /// By default, the editor understands RTL and will automatically switch
        /// the textflow in the editor to RTL based on the current culture settings.
        /// So, if the current culture is Hebrew or Arabic, the textflow in the editor
        /// will automatically switch to RTL. If for whatever reason this is not desirable
        /// and you want to maintain LTR ( the default ) always, then set this property
        /// to false and the default textflow will be respected.
        /// </summary>
        [DefaultValue(true)]
        public bool AutoSwitchTextDirection
        {
            get
            {
                return (bool)(ViewState["AutoSwitchTextDirection"] ?? true);
            }
            set
            {
                ViewState["AutoSwitchTextDirection"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the Cells designer is loading for the first time. The default
        /// text is : Loading table cells designer...
        /// </summary>
        [DefaultValue("Loading table cells designer...")]
        public string CellsDesignerLoadingMessage
        {
            get
            {
                return (ViewState["CellsDesignerLoadingMessage"] == null) ?
                    GetLocalizedText("CellsDesignerLoadingMessage") :
                    (string)ViewState["CellsDesignerLoadingMessage"];
            }
            set { ViewState["CellsDesignerLoadingMessage"] = value; }
        }

        /// <summary>
        /// Occurs clientside when a color is selected via the ColorPicker used by the HTML Editor for all color 
        /// selection operations
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when a color is selected in the color palette")]
        public string ClientSideColorSelect
        {
            get
            {
                object o = ViewState["ClientSideColorSelect"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideColorSelect"] = value; }
        }

        /// <summary>
        /// Occurs clientside when the font name dropdownlist close button is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when clicking outside the FontName ddl")]
        public string ClientSideFontNameDropDownClose
        {
            get
            {
                object o = ViewState["ClientSideFontNameDropDownClose"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideFontNameDropDownClose"] = value; }
        }

        /// <summary>
        /// Occurs clientside when a font name is selected 
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when selecting an item in the FontName ddl")]
        public string ClientSideFontNameDropDownSelect
        {
            get
            {
                object o = ViewState["ClientSideFontNameDropDownSelect"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideFontNameDropDownSelect"] = value; }
        }

        /// <summary>
        /// Occurrs clientside when the fontsize dropdownlist close button is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when clicking outside the FontSize ddl")]
        public string ClientSideFontSizeDropDownClose
        {
            get
            {
                object o = ViewState["ClientSideFontSizeDropDownClose"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideFontSizeDropDownClose"] = value; }
        }

        /// <summary>
        /// Occurs clientside when the font size is selected
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when selecting an item in the FontSize ddl")]
        public string ClientSideFontSizeDropDownSelect
        {
            get
            {
                object o = ViewState["ClientSideFontSizeDropDownSelect"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideFontSizeDropDownSelect"] = value; }
        }

        /// <summary>
        /// Occurrs clientside when the format block dropdownlist close button is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when clicking outside the FormatBlock ddl")]
        public string ClientSideFormatBlockDropDownClose
        {
            get
            {
                object o = ViewState["ClientSideFormatBlockDropDownClose"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideFormatBlockDropDownClose"] = value; }
        }

        /// <summary>
        /// Occurrs clientside when a format block is selected
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when selecting an item in the FormatBlock ddl")]
        public string ClientSideFormatBlockDropDownSelect
        {
            get
            {
                object o = ViewState["ClientSideFormatBlockDropDownSelect"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideFormatBlockDropDownSelect"] = value; }
        }

        /// <summary>
        /// Occurs clientside when the maximum length of characters is reached.
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when MaxLength is reached")]
        public string ClientSideMaxLengthReached
        {
            get
            {
                object o = ViewState["ClientSideMaxLengthReached"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideMaxLengthReached"] = value; }
        }

        /// <summary>
        /// Occurs clientside when the close button on one of the modal popup dialogs is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when the close button is clicked on the popup window")]
        public string ClientSidePopupCloseButtonClick
        {
            get
            {
                object o = ViewState["ClientSidePopupCloseButtonClick"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSidePopupCloseButtonClick"] = value; }
        }

        /// <summary>
        /// Occurs after the data was already processed by the server ( and possibly saved serverside). 
        /// This is the last event that fires when clicking the save button.
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when the save butotn is clicked")]
        public string ClientSideSaved
        {
            get
            {
                object o = ViewState["ClientSideSaved"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideSaved"] = value; }
        }

        /// <summary>
        /// Occurs when the save button is clicked in the editor but before a save operation takes place (on the client)
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when clicking the save button is clicked")]
        public string ClientSideSaving
        {
            get
            {
                object o = ViewState["ClientSideSaving"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideSaving"] = value; }
        }

        /// <summary>
        /// Occurs clientside when a tab item is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when a tab item is clicked")]
        public string ClientSideTabItemClick
        {
            get
            {
                object o = ViewState["ClientSideTabItemClick"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideTabItemClick"] = value; }
        }

        /// <summary>
        /// Occurs clientside when an item in the toolBar is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when a toolBar item is clicked")]
        public string ClientSideToolBarItemClick
        {
            get
            {
                object o = ViewState["ClientSideToolBarItemClick"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideToolBarItemClick"] = value; }
        }

        /// <summary>
        /// Occurs clientside when a custom dropdownlist added to the toolbar is clicked
        /// </summary>
        [DefaultValue(""),
        Category("ClientSide Events"),
        Description("Occurs when a toolBar options item is clicked")]
        public string ClientSideToolBarOptionsItemClick
        {
            get
            {
                object o = ViewState["ClientSideToolBarOptionsItemClick"];
                return (o == null) ? string.Empty : o.ToString();
            }
            set { ViewState["ClientSideToolBarOptionsItemClick"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when code hilighting is in progress. The default text is : 
        /// Code highlighting in progress...
        /// </summary>
        [DefaultValue("Code highlighting in progress...")]
        public string CodeHighlightingMessage
        {
            get
            {
                return (ViewState["CodeHighlightingMessage"] == null) ?
                    GetLocalizedText("CodeHighlightingMessage") : ViewState["CodeHighlightingMessage"].ToString();
            }
            set { ViewState["CodeHighlightingMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when the is loading for the code highlighter for the
        /// first time. The default text is : Loading code highlighter...
        /// </summary>
        [DefaultValue("Loading code highlighter...")]
        public string CodeHilighterLoadingMessage
        {
            get
            {
                return (ViewState["CodeHilighterLoadingMessage"] == null) ?
                    GetLocalizedText("CodeHilighterLoadingMessage") : ViewState["CodeHilighterLoadingMessage"].ToString();
            }
            set { ViewState["CodeHilighterLoadingMessage"] = value; }
        }

        [DefaultValue("Typps_Editor")]
        public override string CssClass
        {
            get
            {
                return base.CssClass;
            }
            set
            {
                base.CssClass = value;
            }
        }

        /// <summary>
        /// CSS classes to display arranged in a dropdownlist. This allows you to provide setting
        /// classes on HTML elements from within the editor itself in DesignView
        /// </summary>
        [Category("Behavior"),
        Description("A collection of css class styles"),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        Editor(typeof(Typps.CssClassNameEditor), typeof(System.Drawing.Design.UITypeEditor)),
        PersistenceMode(PersistenceMode.InnerProperty)]
        public CssClassNameCollection CssClassNamesList
        {
            get
            {
                if (_cssClassNamesList == null)
                    _cssClassNamesList = new CssClassNameCollection();
                if (IsTrackingViewState)
                {
                    ((IStateManager)(_cssClassNamesList)).TrackViewState();
                }
                return _cssClassNamesList;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the Css class names list populates for the first time.
        /// The default text is : Loading css style class list...
        /// </summary>
        [DefaultValue("Loading css style class list...")]
        public string CssStyleMessage
        {
            get
            {
                return (ViewState["CssStyleMessage"] == null) ?
                    GetLocalizedText("CssStyleMessage") : ViewState["CssStyleMessage"].ToString();
            }
            set { ViewState["CssStyleMessage"] = value; }
        }

        /// <summary>
        /// Gets the collection of DictionaryItems
        /// </summary>
        [Category("Behavior"),
        Description("A collection of dictionaries."),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        Editor(typeof(Typps.DictionaryEditor), typeof(System.Drawing.Design.UITypeEditor)),
        PersistenceMode(PersistenceMode.InnerProperty)]
        public DictionaryCollection Dictionaries
        {
            get
            {
                if (_dictionaries == null)
                    _dictionaries = new DictionaryCollection();
                if (IsTrackingViewState)
                {
                    ((IStateManager)(_dictionaries)).TrackViewState();
                }
                return _dictionaries;
            }
        }

        /// <summary>
        /// The direction of the ToolBar, Tabs and Textflow of the editor.
        /// This is automatic and you shouldn't need to set this property manually.
        /// Rather you may instead want to set the cultureinfo for the current thread
        /// early, based on that the editor will automatically use the correct direction.
        /// </summary>
        [DefaultValue(typeof(Dir), "LTR")]
        public Dir Direction
        {
            get
            {
                return (Dir)(ViewState["Direction"] ?? Dir.LTR);
            }
            set
            {
                ViewState["Direction"] = value;
            }
        }

        /// <summary>
        /// The color used when fading out a disabled toolBar item or a tab.
        /// Default is white
        /// </summary>
        [TypeConverter(typeof(WebColorConverter)),
        DefaultValue(typeof(Color), "#d5d5d2")]
        public Color DisabledButtonBackColor
        {
            get
            {
                return (ViewState["DisabledButtonBackColor"] == null) ?
                    ColorTranslator.FromHtml("#d5d5d2") : (Color)ViewState["DisabledButtonBackColor"];
            }
            set
            {
                ViewState["DisabledButtonBackColor"] = value;
            }
        }

        /// <summary>
        /// The border color used when a toolBar item or tab is disabled. This is application only in Icons mode and ignored in imagesprites.
        /// The default is gray
        /// </summary>
        [TypeConverter(typeof(WebColorConverter)),
        DefaultValue(typeof(Color), "#bfbfbd")]
        public Color DisabledButtonBorderColor
        {
            get
            {
                return (ViewState["DisabledButtonBorderColor"] == null) ?
                    ColorTranslator.FromHtml("#bfbfbd") : (Color)ViewState["DisabledButtonBorderColor"];
            }
            set
            {
                ViewState["DisabledButtonBorderColor"] = value;
            }
        }

        /// <summary>
        /// The tranparency used when an element is disabled in the toolBar or
        /// a disabled tab. This value fades out the element making it seem disabled.
        /// Default is 60.
        /// </summary>
        [DefaultValue(60)]
        public int DisabledButtonTransparency
        {
            get
            {
                return (ViewState["DisabledButtonTransparency"] == null) ?
            60 : (int)ViewState["DisabledButtonTransparency"];
            }
            set
            {
                ViewState["DisabledButtonTransparency"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the color used in the toolBar block strip displayed over the icons, 
        /// when not in designview to avoid interaction. 
        /// </summary>
        [DefaultValue(typeof(Color), ""),
        Description("The block screen color"),
        TypeConverter(typeof(WebColorConverter)),
        Category("Appearance")]
        public Color DisabledToolBarShaderColor
        {
            get { return (ViewState["DisabledToolBarShaderColor"] == null) ? Color.Empty : (Color)ViewState["DisabledToolBarShaderColor"]; }
            set { ViewState["DisabledToolBarShaderColor"] = value; }
        }

        /// <summary>
        /// Gets/Sets the Save button caption when in downlevel mode. The default is : Save
        /// </summary>
        [DefaultValue("Save")]
        public string DownLevelSaveButtonText
        {
            get
            {
                return (string)(ViewState["DownLevelSaveButtonText"] ?? "Save");
            }
            set
            {
                ViewState["DownLevelSaveButtonText"] = value;
            }
        }

        [DefaultValue(250)]
        public int DropDownListEffectDuration
        {
            get
            {
                return (int)(ViewState["DropDownListEffectDuration"] ?? 250);
            }
            set
            {
                ViewState["DropDownListEffectDuration"] = value;
            }
        }

        /// <summary>
        /// The dtd schema to use. By default XhtmlTransitional is used. This means the html is validated for
        /// an Xhtml Transitional doctype. You can choose between Transitional, Frameset and Strict doctypes.
        /// </summary>
        [DefaultValue(typeof(DtdSchema), "XhtmlTransitional")]
        public DtdSchema DtdSchema
        {
            get
            {
                return (DtdSchema)(ViewState["DtdSchema"] ?? DtdSchema.XhtmlTransitional);
            }
            set
            {
                ViewState["DtdSchema"] = value;
            }
        }

        /// <summary>
        /// Only elements and attributes provided in this List will be permitted 
        /// while everything else is stripped.
        /// </summary>
        public List<ElementPair> ElementsAllowed
        {
            get
            {
                if (_elementsAllowed == null)
                    _elementsAllowed = new List<ElementPair>();
                return _elementsAllowed;
            }
        }

        /// <summary>
        /// Gets the Embedded color picker. This is an instance of the color picker used by the HTML Editor 
        /// everytime there is a command that requires color selection. 
        /// </summary>
        [PersistenceMode(PersistenceMode.InnerProperty),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ColorPicker EmbeddedColorPicker
        {
            get
            {
                if (_embeddedColorPicker == null)
                    _embeddedColorPicker = new ColorPicker();
                return _embeddedColorPicker;
            }
        }

        /// <summary>
        /// Gets the Embedded image picker. This is an instance of the image picker used by the HTML Editor 
        /// for image selection/viewing operations.
        /// </summary>
        [PersistenceMode(PersistenceMode.InnerProperty),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ImagePicker EmbeddedImagePicker
        {
            get
            {
                if (_embeddedImagePicker == null)
                    _embeddedImagePicker = new ImagePicker();
                return _embeddedImagePicker;
            }
        }

        /// <summary>
        /// Gets the Embedded UpdatePanelProgress control. This is an instance of the UpdatePanelProgress
        /// used by the HTML Editor everytime an asyc callback is executed. 
        /// </summary>
        [PersistenceMode(PersistenceMode.InnerProperty),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public UpdatePanelProgress EmbeddedUpdatePanelProgress
        {
            get
            {
                if (_embeddedUpdatePanelProgress == null)
                    _embeddedUpdatePanelProgress = new UpdatePanelProgress();
                return _embeddedUpdatePanelProgress;
            }
        }

        /// <summary>
        /// Gets/Sets a value that enables a slide effect on dropdownlists. The default is true.
        /// </summary>
        [DefaultValue(true)]
        public bool EnableDropDownListEffects
        {
            get
            {
                return (bool)(ViewState["EnableDropDownListEffects"] ?? true);
            }
            set
            {
                ViewState["EnableDropDownListEffects"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating that a browse server button is displayed right beside the url 
        /// text field in the hyperlink designer window. The default is false.
        /// </summary>
        [DefaultValue(false)]
        public bool EnableFileBrowser
        {
            get
            {
                return (bool)(ViewState["EnableFileBrowser"] ?? false);
            }
            set
            {
                ViewState["EnableFileBrowser"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating a file upload option is available in the File Browser window. 
        /// The default is true.
        /// </summary>
        [DefaultValue(true)]
        public bool EnableFileUpload
        {
            get
            {
                return (bool)(ViewState["EnableFileUpload"] ?? true);
            }
            set
            {
                ViewState["EnableFileUpload"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating the Save button is enabled/disabled. The default is true
        /// </summary>
        [DefaultValue(true)]
        public bool EnableSaveButton
        {
            get
            {
                return (bool)(ViewState["EnableSaveButton"] ?? true);
            }
            set
            {
                ViewState["EnableSaveButton"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a boolean value to control whether the syntax highlighter should output inline css or not. 
        /// By default this is true, meaning inline css is used.
        /// </summary>
        [DefaultValue(true)]
        public bool EnableSyntaxHighlighterInlineCss
        {
            get
            {
                return (bool)(ViewState["EnableSyntaxHighlighterInlineCss"] ?? true);
            }
            set
            {
                ViewState["EnableSyntaxHighlighterInlineCss"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating that the toolBar is floated on the page
        /// </summary>
        [DefaultValue(false),
        Category("Floating toolBar")]
        public bool EnableToolBarFloat
        {
            get
            {
                return (ViewState["EnableToolBarFloat"] == null) ?
                    false : (bool)ViewState["EnableToolBarFloat"];
            }
            set
            {
                ViewState["EnableToolBarFloat"] = value;
            }
        }

        /// <summary>
        /// Ensures that viewstate is not saved for the Text property of this editor. You do not
        /// need to save this data in viewstate. It's collected from the pages form collection
        /// on postback, so quite un-necessary. Still if your circumstance requires that you
        /// enable viewstate on the text property, set this value to true.
        /// </summary>
        [DefaultValue(false)]
        public bool EnableViewStateOnRichText
        {
            get
            {
                return (bool)(ViewState["EnableViewStateOnRichText"] ?? false);
            }
            set
            {
                ViewState["EnableViewStateOnRichText"] = value;
            }
        }

        /// <summary>
        /// Displays a message dialog when the editor has validated the markup and made changes when it met errors.
        /// By default this is false and no notificatoin is displayed even though the corrections are logged and viewable the user when
        /// clicking the error log icon.
        /// </summary>
        [DefaultValue(false)]
        public bool ErrorLogNotification
        {
            get
            {
                return (bool)(ViewState["ErrorLogNotification"] ?? false);
            }
            set
            {
                ViewState["ErrorLogNotification"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets an array of Absolute Urls to stylesheet documents referenced the HTML Editor. Ensure that the urls are
        /// Absolute as relative URLS aren't gauranteed to resolve due to the baseURL being blank on the iframe hosting the editor. Eg. http://www.yoursite.com/stylesheet.css
        /// </summary>
        [TypeConverter(typeof(NewLineListSeparatorConverter)),
        Editor("System.Windows.Forms.Design.StringArrayEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        public string[] ExternalStyleSheetReferences
        {
            get
            {
                string[] strArray = (string[])ViewState["ExternalStyleSheetReferences"];
                if (strArray != null)
                {
                    return strArray;
                }
                return new string[0];
            }
            set
            {
                ViewState["ExternalStyleSheetReferences"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets an array of stylesheets referenced by the page hosting the editor to be inherited by the editor.
        /// By default stylesheets in the page aren't inherited. 
        /// Passing an array of stylesheet file names referenced by the page,
        /// ensures that the editor inherits those stylesheets.
        /// For example if in your page you have a style sheet referenced as : <link href="url/to/my/external.css" type="text/css" rel="stylesheet" />
        /// then you would pass only the file name "external.css" to the ExternalStyleSheets property ;
        /// If you have more than 1 file, then "external.css, external2.css" if your setting this declaratively or add items to the array if set in code
        /// </summary>
        [TypeConverter(typeof(NewLineListSeparatorConverter)),
        Editor("System.Windows.Forms.Design.StringArrayEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        public string[] ExternalStyleSheets
        {
            get
            {
                string[] strArray = (string[])ViewState["ExternalStyleSheets"];
                if (strArray != null)
                {
                    return strArray;
                }
                return new string[0];
            }
            set
            {
                ViewState["ExternalStyleSheets"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the File Browser is loading for the first time. 
        /// The default text is : Loading server browser...
        /// </summary>
        [DefaultValue("Loading server browser...")]
        public string FileBrowserLoadingMessage
        {
            get { return (ViewState["FileBrowserLoadingMessage"] == null) ? GetLocalizedText("FileBrowser_LoadingMessage") : ViewState["FileBrowserLoadingMessage"].ToString(); }
            set { ViewState["FileBrowserLoadingMessage"] = value; }
        }

        /// <summary>
        /// The top level root node for the file gallery. Populate this top level node 
        /// when building a file gallery that is triggered via
        /// the Browser Server button displayed in the Hyperlink designer
        /// </summary>
        [Browsable(false)]
        public HTreeNode FileGalleryNode
        {
            get
            {
                if (_fileGalleryNode == null)
                    _fileGalleryNode = new HTreeNode();
                return _fileGalleryNode;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when a file is being uploaded to the server. 
        /// The default text is : Uploading file. Please wait for upload to complete...
        /// </summary>
        [DefaultValue("Uploading file. Please wait for upload to complete...")]
        public string FileUploaderProgress
        {
            get { return (ViewState["FileUploaderProgress"] == null) ? GetLocalizedText("FileUpload_FileUploaderProgress") : ViewState["FileUploaderProgress"].ToString(); }
            set { ViewState["FileUploaderProgress"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when the "Upload" button displayed in the File browser window
        /// is clicked for the first time. The default text is : File uploader loading...
        /// </summary>
        [DefaultValue("File uploader loading...")]
        public string FileUploadingMessage
        {
            get { return (ViewState["FileUploadingMessage"] == null) ? GetLocalizedText("FileUpload_FileUploadingMessage") : ViewState["FileUploadingMessage"].ToString(); }
            set { ViewState["FileUploadingMessage"] = value; }
        }

        /// <summary>
        /// Set a filter of mime types you want the file upload button to display when
        /// the user tries to upload. Supply a comma separated list of mime types eg :
        /// image/gif,image/jpeg ; Reference for details : 
        /// http://msdn.microsoft.com/en-us/library/ms533060(VS.85).aspx
        /// Note: The accept attribute is not properly supported by any of the major browsers so
        /// make sure you have validation code serverside.
        /// </summary>
        [DefaultValue("")]
        public string FileUploadMimeFilter
        {
            get
            {
                return (string)(ViewState["FileUploadMimeFilter"] ?? string.Empty);
            }
            set
            {
                ViewState["FileUploadMimeFilter"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating where malformed html should be fixed automatically by the editor.
        /// The default is true
        /// </summary>
        [DefaultValue(true)]
        public bool FixHtml
        {
            get
            {
                return (ViewState["FixHtml"] == null) ?
                    true : (bool)ViewState["FixHtml"];
            }
            set { ViewState["FixHtml"] = value; }
        }

        /// <summary>
        /// Gets/Sets the tooltip to display when the mousing over the close button used to hide the floating
        /// toolBar when it is active. The default tooltip is :
        /// Closes ToolBar. You can click in the editor again to enable this toolBar.
        /// </summary>
        [DefaultValue("Closes ToolBar. You can click in the editor again to enable this toolBar."),
        Category("Floating toolBar")]
        public string FloatingToolBarCloseTooltip
        {
            get
            {
                return (ViewState["FloatingToolBarCloseTooltip"] == null) ?
                    GetLocalizedText("FloatingToolBarCloseTooltip")
                    : (string)ViewState["FloatingToolBarCloseTooltip"];
            }
            set
            {
                ViewState["FloatingToolBarCloseTooltip"] = value;
            }
        }

        /// <summary>
        /// A list of fontNames to display in the Font name DropDownList, supported by the editor. By default 10 fonts are used. Providing your own list of fonts clears the defaults
        /// and uses the values supplied to this property instead.
        /// </summary>
        [TypeConverter(typeof(NewLineListSeparatorConverter)),
        Editor("System.Windows.Forms.Design.StringArrayEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        public string[] FontNames
        {
            get
            {
                string[] strArray = (string[])ViewState["FontNames"];
                if (strArray != null)
                {
                    return strArray;
                }
                return new string[0];
            }
            set
            {
                ViewState["FontNames"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets a value indicating whether code should be formatted when switching into HTML View. 
        /// The default is true
        /// </summary>
        [DefaultValue(true)]
        public bool FormatCodeInHtmlView
        {
            get
            {
                return (ViewState["FormatCodeInHtmlView"] == null) ?
                    true : (bool)ViewState["FormatCodeInHtmlView"];
            }
            set { ViewState["FormatCodeInHtmlView"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display in the FormatBlock dropdownlist for "Heading"
        /// The default is simply : Heading
        /// </summary>
        [DefaultValue("Heading"),
        Category("FormatBlock Label"),
        Description("Heading label")]
        public string Heading
        {
            get
            {
                object o = ViewState["Heading"];
                if (o == null)
                    o = GetLocalizedText("Heading");
                return (string)o;
            }
            set { ViewState["Heading"] = value; }
        }

        [DefaultValue(typeof(Unit), "200px")]
        public override Unit Height
        {
            get
            {
                return base.Height;
            }
            set
            {
                base.Height = value;
            }
        }

        /// <summary>
        /// The HtmlStripMode is valid when you have already added a list of Html elements
        /// in the ElementsAllowed collection (exposed as propert of the same name).
        /// TagAndContent strip means that the html element along with whatever data it contains
        /// will be stripped out. While TagOnly means that only the tag is stripped while preserving the
        /// contents of the element. Note that in either case however, if the following situation presents itself
        /// eg: <div><span></span></div> and div is an element that is supposed to be stripped while span
        /// being an element that is allowed, the div is stripped while preserving the span. This happens
        /// regardless of the setting TagAndContent.
        /// </summary>
        [DefaultValue(typeof(StripMode), "TagAndContent")]
        public StripMode HtmlStripMode
        {
            get
            {
                return (StripMode)(ViewState["HtmlStripMode"] ?? StripMode.TagAndContent);
            }
            set
            {
                ViewState["HtmlStripMode"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the editor makes a callback from the client,
        /// normally when switching from HTMLView/DesignView and vice versa.
        /// The default is : Fixing erroneous html if any...
        /// </summary>
        [DefaultValue("Fixing erroneous html if any...")]
        public string HtmlValidationMessage
        {
            get { return (ViewState["HtmlValidationMessage"] == null) ? GetLocalizedText("HtmlValidationMessage") : ViewState["HtmlValidationMessage"].ToString(); }
            set { ViewState["HtmlValidationMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when switching to readonly HtmlView that is color coded, for 
        /// easy reading.
        /// The default text is : Colorizing html with color code...
        /// </summary>
        [DefaultValue("Colorizing html with color code...")]
        public string HtmlViewHilightMessage
        {
            get { return (ViewState["HtmlViewHilightMessage"] == null) ? GetLocalizedText("HtmlViewHilightMessage") : ViewState["HtmlViewHilightMessage"].ToString(); }
            set { ViewState["HtmlViewHilightMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when the Hyperlink designer is loading for the first time.
        /// The default text is : Loading hyperlink designer...
        /// </summary>
        [DefaultValue("Loading hyperlink designer...")]
        public string HyperlinkDesignerLoadingMessage
        {
            get { return (ViewState["HyperlinkDesignerLoadingMessage"] == null) ? GetLocalizedText("HyperLinkDesignerLoadingMessage") : ViewState["HyperlinkDesignerLoadingMessage"].ToString(); }
            set { ViewState["HyperlinkDesignerLoadingMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the display mode of the toolBar. When displaying the toolBar in Icons mode, individual
        /// icons are used which can be a resource hog depending on your usage scenario. This is also the 
        /// default mode. This is because customizations are easier in icons mode and the taxation maybe 
        /// well worth. Whereas when the toolBar is displayed in ImageSprites mode, Icons are grouped in
        /// single image blocks. This is a good optimization. It's also easier to design icons when
        /// using this mode. The default is : Icons
        /// </summary>
        [DefaultValue(typeof(IconType), "Icons"),
        Category("Image sprites or individual icons?"),
        RefreshProperties(RefreshProperties.Repaint)]
        public IconType IconsMode
        {
            get
            {
                return (ViewState["IconsMode"] == null) ?
                    IconType.Icons : (IconType)ViewState["IconsMode"];
            }
            set
            {
                ViewState["IconsMode"] = value;
                if (DesignMode)
                    ResetCollectionsAndStyles();

            }
        }

        /// <summary>
        /// Gets a value indcating whether the request is a callback caused by HTML Editor. This is used
        /// for use by the HTML Editor internally and is not intended for user code
        /// </summary>
        [Browsable(false)]
        public override bool IsCallback
        {
            get
            {
                if (DesignMode || Context == null) return false;
                if (!IsBrowserUpLevel) return false;
                EnsureChildControls();
                string key = string.Format("iscallback${0}", UniqueID);
                string value = Context.Request.Form[key];
                if (!string.IsNullOrEmpty(value))
                    return true;
                return _embeddedImagePicker.IsCallback;
            }
        }

        /// <summary>
        /// Gets a value indicating a file upload request
        /// </summary>
        [Browsable(false)]
        public bool IsFileUploading
        {
            get
            {
                if (DesignMode) return false;
                string value = Context.Request.Form[Page.postEventSourceID];
                string id = this.ClientID + "_fileupload";
                if (!string.IsNullOrEmpty(value))
                    if (value == id)
                        return true;
                return false;
            }
        }

        /// <summary>
        /// Gets a value indicating a multi file upload request
        /// </summary>
        [Browsable(false)]
        public bool IsMultiFileUploading
        {
            get
            {
                if (DesignMode) return false;
                string value = Context.Request.Form[Page.postEventSourceID];
                string id = this.ClientID + "_multifileuploader";
                if (!string.IsNullOrEmpty(value))
                    if (value == id)
                        return true;
                return false;
            }
        }

        /// <summary>
        /// Gets or sets the maximum number of characters allowed in the editor. When this is enabled, a check for the max characters is performed on the clientside and in additional
        /// a check is performed serverside to compensate for downlevel mode. If the max length is reached a MaxLengthReached event is fired allowing you to take action appropriately
        /// both on the server and clientside. The default is 0, which indicates that the property is not set.
        /// </summary>
        [DefaultValue(0)]
        public int MaxLength
        {
            get
            {
                return (int)(ViewState["MaxLength"] ?? 0);
            }
            set
            {
                ViewState["MaxLength"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the Multi file uploader is activated for the first time. 
        /// The default text is : Multi file uploader loading...
        /// </summary>
        [DefaultValue("Multi file uploader loading...")]
        public string MultiFileUploaderLoading
        {
            get { return (ViewState["MultiFileUploaderLoading"] == null) ? GetLocalizedText("MultiFileUploaderLoading") : ViewState["MultiFileUploaderLoading"].ToString(); }
            set { ViewState["MultiFileUploaderLoading"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when a multi file upload is in progress.
        /// The default text is : Uploading files. Please wait for upload to complete...
        /// </summary>
        [DefaultValue("Uploading files. Please wait for upload to complete...")]
        public string MultiFileUploaderProgress
        {
            get { return (ViewState["MultiFileUploaderProgress"] == null) ? GetLocalizedText("MultiFileUploaderProgress") : ViewState["MultiFileUploaderProgress"].ToString(); }
            set { ViewState["MultiFileUploaderProgress"] = value; }
        }

        /// <summary>
        /// Set a filter of mime types you want the Multi-File upload button to display when
        /// the user tries to upload. Supply a comma separated list of mime types eg :
        /// image/gif,image/jpeg ; Reference for details : 
        /// http://msdn.microsoft.com/en-us/library/ms533060(VS.85).aspx
        /// Note: The accept attribute is not properly supported by any of the major browsers so
        /// make sure you have validation code serverside.
        /// </summary>
        [DefaultValue("")]
        public string MultiFileUploadMimeFilter
        {
            get
            {
                return (string)(ViewState["MultiFileUploadMimeFilter"] ?? string.Empty);
            }
            set
            {
                ViewState["MultiFileUploadMimeFilter"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the editor finds references to file system files
        /// that require to be uploaded. The default text is : Upload required for {0}
        /// </summary>
        [DefaultValue("Upload required for {0}")]
        public string MultiFileUploadRequiredMessage
        {
            get { return (ViewState["MultiFileUploadRequiredMessage"] == null) ? GetLocalizedText("MultiFileUploadRequiredMessage") : ViewState["MultiFileUploadRequiredMessage"].ToString(); }
            set { ViewState["MultiFileUploadRequiredMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display in the FormatBlock dropdownlist for "Paragraph"
        /// The default is simply : Paragraph
        /// </summary>
        [DefaultValue("Paragraph"),
        Category("FormatBlock Label"),
        Description("Paragraph label")]
        public string Paragraph
        {
            get
            {
                object o = ViewState["Paragraph"];
                if (o == null)
                    o = GetLocalizedText("Paragraph");
                return (string)o;
            }
            set { ViewState["Paragraph"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display in the FormatBlock dropdownlist for "Preformatted"
        /// The default is simply : Preformatted
        /// </summary>
        [DefaultValue("Pre formatted"),
        Category("FormatBlock Label"),
        Description("Preformat label")]
        public string Preformatted
        {
            get
            {
                object o = ViewState["Preformatted"];
                if (o == null)
                    o = GetLocalizedText("Preformatted");
                return (string)o;
            }
            set { ViewState["Preformatted"] = value; }
        }

        /// <summary>
        /// Gets/Sets a value indicating whether the HTML Editor should make a regular postback or a silent
        /// async callback in the background for saving HTML when the save icon is clicked. 
        /// The default is true
        /// </summary>
        [DefaultValue(true)]
        public bool RegisterAsyncPostBackSaveTrigger
        {
            get
            {
                object o = (object)ViewState["RegisterAsyncPostBackSaveTrigger"];
                return (o == null) ? true : (bool)o;
            }
            set { ViewState["RegisterAsyncPostBackSaveTrigger"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when the save icon on the HTML editor is clicked.
        /// The default text is : Saving in progress...
        /// </summary>
        [DefaultValue("Saving in progress...")]
        public string RichTextSavingMessage
        {
            get { return (ViewState["RichTextSavingMessage"] == null) ? GetLocalizedText("RichTextSavingMessage") : ViewState["RichTextSavingMessage"].ToString(); }
            set { ViewState["RichTextSavingMessage"] = value; }
        }

        /// <summary>
        /// The block screen background color when a modal dialog is displayed by the HTML Editor
        /// </summary>
        [DefaultValue(typeof(Color), ""),
        Description("Block screen background color"),
        TypeConverter(typeof(WebColorConverter)),
        Category("Appearance")]
        public Color ShaderColor
        {
            get { return (ViewState["ShaderColor"] == null) ? Color.Empty : (Color)ViewState["ShaderColor"]; }
            set { ViewState["ShaderColor"] = value; }
        }

        /// <summary>
        /// The block screen background opacity when a modal dialog is displayed by the HTML Editor
        /// </summary>
        [DefaultValue(50),
        Description("Block screen background opacity"),
        TypeConverter(typeof(WebColorConverter)),
        Category("Appearance")]
        public int ShaderOpacity
        {
            get { return (ViewState["ShaderOpacity"] == null) ? 50 : (int)ViewState["ShaderOpacity"]; }
            set { ViewState["ShaderOpacity"] = value; }
        }

        /// <summary>
        /// Gets/Sets a value indicating whether markup corrections performed by the editor should be 
        /// logged in the error log (accessible through one of the tabs)
        /// </summary>
        [DefaultValue(true)]
        public bool ShowHtmlMarkupErrorLog
        {
            get { return (ViewState["ShowMarkupErrorLog"] == null) ? true : (bool)ViewState["ShowMarkupErrorLog"]; }
            set { ViewState["ShowMarkupErrorLog"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when the spell checker icon is clicked for the first time.
        /// The default text is : Loading supported languages...
        /// </summary>
        [DefaultValue("Loading supported languages...")]
        public string SpellCheckerLoadingMessage
        {
            get { return (ViewState["SpellCheckerLoadingMessage"] == null) ? GetLocalizedText("SpellCheckerLoadingMessage") : ViewState["SpellCheckerLoadingMessage"].ToString(); }
            set { ViewState["SpellCheckerLoadingMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when the document is being spell checked.
        /// The default text is : Spell checking in progress...
        /// </summary>
        [DefaultValue("Spell checking in progress...")]
        public string SpellCheckingMessage
        {
            get { return (ViewState["SpellCheckingMessage"] == null) ? GetLocalizedText("SpellCheckingMessage") : ViewState["SpellCheckingMessage"].ToString(); }
            set { ViewState["SpellCheckingMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the header caption displayed in the spell checker suggestion dropdownlist. 
        /// The default text is : Suggestion box
        /// </summary>
        [DefaultValue("Suggestion box")]
        public string SuggestionListHeaderTitle
        {
            get { return (ViewState["SuggestionListHeaderTitle"] == null) ? GetLocalizedText("SuggestionListHeaderTitle") : (string)ViewState["SuggestionListHeaderTitle"]; }
            set { ViewState["SuggestionListHeaderTitle"] = value; }
        }

        /// <summary>
        /// Gets/Sets the label used for the ignore word command that is displayed in the spellchecker suggestion
        /// box. The default text is : Ignore word
        /// </summary>
        [DefaultValue("Ignore word")]
        public string SuggestionListIgnoreLabel
        {
            get { return (ViewState["SuggestionListIgnoreLabel"] == null) ? GetLocalizedText("SuggestionListIgnoreLabel") : (string)ViewState["SuggestionListIgnoreLabel"]; }
            set { ViewState["SuggestionListIgnoreLabel"] = value; }
        }

        /// <summary>
        /// Not for use in code. TabContainerWidth specifies the Width 
        /// for the _tabContainer ( used when IconsMode is set to ImageSprites).
        /// This allows proper sizing of _tabContainer in RTL mode. Best set in a 
        /// theme in the tabsdefaultsadvanced.xml or tabsdefaultsbasic.xml file
        /// and is the size of the image sprite used for tabs.
        /// </summary>
        [Browsable(false)]
        public Unit TabContainerWidth
        {
            get
            {
                return _tabContainerWidth;
            }
            set
            {
                _tabContainerWidth = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the table designer is loading for the first time. 
        /// The default text is : Loading table designer...
        /// </summary>
        [DefaultValue("Loading table designer...")]
        public string TableDesignerLoadingMessage
        {
            get { return (ViewState["TableDesignerLoadingMessage"] == null) ? GetLocalizedText("TableDesignerLoadingMessage") : ViewState["TableDesignerLoadingMessage"].ToString(); }
            set { ViewState["TableDesignerLoadingMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the Url to the Image displayed in the tab containers Left edge
        /// </summary>
        [Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(UITypeEditor)),
        DefaultValue(""),
        NotifyParentProperty(true)]
        public string TabLeftBorderImage
        {
            get
            {
                return (ViewState["TabLeftBorderImage"] == null) ? string.Empty : (string)ViewState["TabLeftBorderImage"];
            }
            set { ViewState["TabLeftBorderImage"] = value; }
        }

        /// <summary>
        /// Gets a collection of TabItem objects
        /// </summary>
        [Category("Behavior"),
        Description("A collection of Tabs "),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        Editor(typeof(Typps.TabCollectionEditor), typeof(System.Drawing.Design.UITypeEditor)),
        PersistenceMode(PersistenceMode.InnerProperty)]
        public TabCollection Tabs
        {
            get
            {
                if (_tabs == null)
                    _tabs = new TabCollection();
                if (IsTrackingViewState)
                {
                    ((IStateManager)(_tabs)).TrackViewState();
                }
                return _tabs;
            }
        }

        /// <summary>
        /// Gets/Sets the html markup in the editor
        /// </summary>
        [Browsable(false),
        DefaultValue("")]
        public virtual string Text
        {
            get
            {
                EnsureChildControls();
                return HttpUtility.HtmlDecode(_textBoxHtmlContainer.Text);
            }
            set
            {
                EnsureChildControls();
                _textBoxHtmlContainer.Text = HttpUtility.HtmlEncode(value);
            }
        }

        /// <summary>
        /// Set/Get the id of an html element designated as the container
        /// for the toolbar buttons. This allows you to to separate the toolbars from the design area.
        /// Also make sure that you did not enable the floating toolbar (by setting EnableToolBarFloat=true),
        /// otherwise that setting will take precedence.
        /// </summary>
        [Category("Behavior"),
        DefaultValue(""),
        Description("Custom container for toolbars")]
        public string ToolBarContainerId
        {
            get
            {
                return (string)(ViewState["ToolBarContainerId"] ?? string.Empty);
            }
            set
            {
                ViewState["ToolBarContainerId"] = value;
            }
        }

        /// <summary>
        /// Gets/Sets the toolBar mode of the HTML Editor. Advanced mode is the default where all the toolBar
        /// items are displayed. While in Basic mode, just a handful of commands are supported in the toolBar,
        /// making it idea for blogs/forum posts. This provides an easy shortcut to having to remove/customize
        /// manually
        /// </summary>
        [DefaultValue(typeof(ToolBarType), "Advanced")]
        public ToolBarType ToolBarMode
        {
            get
            {
                return (ViewState["ToolBarMode"] == null) ?
                    ToolBarType.Advanced : (ToolBarType)ViewState["ToolBarMode"];
            }
            set
            {
                ViewState["ToolBarMode"] = value;
                if (DesignMode)
                    ResetCollectionsAndStyles();
            }
        }

        /// <summary>
        /// Gets a collection of ToolBarSet objects
        /// </summary>
        [Category("Behavior"),
        Description("A collection of ToolBarItem's "),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        Editor(typeof(Typps.ToolBarCollectionEditor), typeof(System.Drawing.Design.UITypeEditor)),
        PersistenceMode(PersistenceMode.InnerProperty)]
        public ToolBarCollection ToolBars
        {
            get
            {
                if (_toolBars == null)
                    _toolBars = new ToolBarCollection();
                if (IsTrackingViewState)
                {
                    ((IStateManager)(_toolBars)).TrackViewState();
                }
                return _toolBars;
            }
        }

        /// <summary>
        /// Gets/Sets the url to an image used to divide toolBar items
        /// </summary>
        [Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(UITypeEditor)),
        DefaultValue("toolBar-divider.gif"),
        NotifyParentProperty(true)]
        public string ToolBarSeparatorImage
        {
            get
            {
                return (ViewState["ToolBarSeparatorImage"] == null) ?
                    "toolBar-divider.gif" : (string)ViewState["ToolBarSeparatorImage"];
            }
            set { ViewState["ToolBarSeparatorImage"] = value; }
        }

        [DefaultValue(typeof(Unit), "100%")]
        public override Unit Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                base.Width = value;
            }
        }

        /// <summary>
        /// Gets/Sets the text to display when the the word paste cleaner window loads for the first time. 
        /// The default text is : Loading word paste cleaner...
        /// </summary>
        [DefaultValue("Loading word paste cleaner...")]
        public string WordPasteCleanupLoadingMessage
        {
            get { return (ViewState["WordPasteCleanupLoadingMessage"] == null) ? GetLocalizedText("WordPasteCleanupLoadingMessage") : ViewState["WordPasteCleanupLoadingMessage"].ToString(); }
            set { ViewState["WordPasteCleanupLoadingMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when a word paste cleanup operation is in progress. 
        /// The default text is : MS-Word cleanup in progress...
        /// </summary>
        [DefaultValue("MS-Word cleanup in progress...")]
        public string WordPastingCleanupMessage
        {
            get { return (ViewState["WordPastingCleanupMessage"] == null) ? GetLocalizedText("WordPastingCleanupMessage") : ViewState["WordPastingCleanupMessage"].ToString(); }
            set { ViewState["WordPastingCleanupMessage"] = value; }
        }

        /// <summary>
        /// Gets/Sets the text to display when a list of word suggestions is being loaded in the suggestion
        /// dropdownlist. The default text is : Loading word suggestions...
        /// </summary>
        [DefaultValue("Loading word suggestions...")]
        public string WordSuggestionLoadingMessage
        {
            get { return (ViewState["WordSuggestionLoadingMessage"] == null) ? GetLocalizedText("WordSuggestionLoadingMessage") : ViewState["WordSuggestionLoadingMessage"].ToString(); }
            set { ViewState["WordSuggestionLoadingMessage"] = value; }
        }

        /// <summary>
        /// When using embeded styles eg <style...>.firstclassname{}</style>,
        /// pass to this property only that first class name as in the example. This
        /// will tell the clientside code that all style rules that follow need to be
        /// included in the object element used to host the editor. The iframe element
        /// cannot inherit it's parent pages css. It has it's own document in all effect.
        /// Due to recent changes, this is un-necessary and is used only interally now, phew :-)
        /// </summary>
        [TypeConverter(typeof(NewLineListSeparatorConverter))]
        internal string[] CssClassIdentifiers
        {
            get
            {
                if (_cssClassIdentifiers == null)
                    return new string[0];
                return _cssClassIdentifiers;
            }
            set
            {
                _cssClassIdentifiers = value;
            }
        }

        internal List<string> ImportantClasses
        {
            get
            {
                if (_importantClasses == null)
                    _importantClasses = new List<string>();
                return _importantClasses;
            }
            set { _importantClasses = value; }
        }

        protected override string ClassName
        {
            get
            {
                string cn = (this.CssClass != string.Empty) ? this.CssClass : this.ClientID;
                return cn + " editor";
            }
        }

        protected virtual string ColorPickerSkinFolder
        {
            get
            {
                string url = _colorPickerSkinFolder;
                if (IsCustomSkin)
                    url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        protected override string CssKey
        {
            get { return _cssKey; }
        }

        protected override string KeyFormat
        {
            get
            {
                return _keyFormat;
            }
        }

        protected override bool RenderSharedStyles
        {
            get { return true; }
        }

        protected override bool RenderTreeViewStyles
        {
            get
            {
                return true;
            }
        }

        protected override string RootImageSkinFolder
        {
            get
            {
                string url = _rootImageSkinFolder;
                if (IsCustomSkin)
                    url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        protected override string RootSkinFolder
        {
            get
            {
                string url = _rootSkinFolder;
                if (IsCustomSkin)
                    url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        protected override string RootTemplateSkinFolder
        {
            get
            {
                string url = _rootTemplateSkinFolder;
                if (IsCustomSkin)
                    url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        protected override string StartupCssStyleIdentifier
        {
            get { return "e"; }
        }

        protected override string StyleSheetName
        {
            get
            {
                return _styleSheetName;
            }
        }

        protected virtual string TabsImageSkinFolder
        {
            get
            {
                string url = _tabsImageSkinFolder;
                if (IsCustomSkin)
                    url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        protected virtual string ToolBarSetImageSkinFolder
        {
            get
            {
                string url = _toolBarSetImageSkinFolder;
                if (IsCustomSkin)
                    url = url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        protected virtual string ToolBarsImageSkinFolder
        {
            get
            {
                string url = _toolBarsImageSkinFolder;
                if (IsCustomSkin)
                    url = Helper.GetPhysicalPathByResourceNamespace(url, this);
                return url;
            }
        }

        private string CodeHilightText
        {
            get { return _codeHilightText; }
            set { _codeHilightText = value; }
        }

        private bool DisplaySpellingCompleteMessage
        {
            get { return _displaySpellingCompleteMessage; }
            set { _displaySpellingCompleteMessage = value; }
        }

        private string IgnoredWords
        {
            get { return _ignoredWords; }
            set { _ignoredWords = value; }
        }

        DictionaryItem SelectedDictionaryFile
        {
            get
            {
                DictionaryItem item = null;
                foreach (DictionaryItem di in Dictionaries)
                {
                    if (di.Selected)
                        return di;
                }
                if (Dictionaries.Count > 0)
                {
                    item = Dictionaries[0];
                    item.Selected = true;
                }
                return item;
            }
        }

        private string ValidationMarkup
        {
            get { return _validationMarkup; }
            set { _validationMarkup = value; }
        }

        private string WordCleanupMarkup
        {
            get { return _wordCleanupMarkup; }
            set { _wordCleanupMarkup = value; }
        }

        private string WordForSuggestion
        {
            get { return _wordForSuggestion; }
            set { _wordForSuggestion = value; }
        }

        #endregion Properties

        #region Methods

        public virtual bool CodeHilighterLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;
            else
            {
                CodeHilightText = postedValue;
                return true;
            }
        }

        public override void DataBind()
        {
            this.OnDataBinding(EventArgs.Empty);
            this.EnsureChildControls();
            this.DataBindChildren();
        }

        //spellingcomplete
        public virtual bool DisplaySpellingCompleteMessageLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
            {
                DisplaySpellingCompleteMessage = false;
                return false;
            }
            else
            {
                return true;
            }
        }

        public virtual void DownLevelRender()
        {
            _textBoxHtmlContainer = new TextBoxNoEncode();
            _textBoxHtmlContainer.ID = "editortext";
            _textBoxHtmlContainer.EnableViewState = EnableViewStateOnRichText;
            _textBoxHtmlContainer.TextMode = TextBoxMode.MultiLine;
            _textBoxHtmlContainer.Width = Unit.Parse("100%");
            _textBoxHtmlContainer.Height = Unit.Parse("100%");
            _textBoxHtmlContainer.CssClass = ClassName + "-htmlview";// the same as the iframe
            Controls.Add(new LiteralControl("<li>"));
            Controls.Add(_textBoxHtmlContainer);
            Controls.Add(new LiteralControl("</li>"));
            if (ToolBarMode == ToolBarType.Advanced && EnableSaveButton)
            {
                Controls.Add(new LiteralControl("<li>"));
                Button buttonSave = new Button();
                buttonSave.Style["float"] = "right";
                buttonSave.Style["margin"] = "5px";
                buttonSave.Text = DownLevelSaveButtonText;
                Controls.Add(buttonSave);
                Controls.Add(new LiteralControl("</li>"));
            }
        }

        public Pair FixMarkup(string html, bool wordCleanup)
        {
            html = string.Format("<html><body><div>{0}</div></body></html>", html);

            string error = null;
            if (wordCleanup || AutoCleanupMSWordMarkup)
            {
                MSWordParser m = new MSWordParser();
                html = m.Cleanup(html);
                if (m.ErrorLog.ToString().Trim() != string.Empty)
                    error = m.ErrorLog.ToString();
            }
            if (FixHtml || wordCleanup)
            {
                HtmlDtdParser dtd = new HtmlDtdParser(this.DtdSchema);
                ParsedSourceContent content = dtd.ParseHtml(html);

                error = error != null ? Environment.NewLine + content.FailureMessage : content.FailureMessage;

                html = content.Source;
            }
            int startIndex = html.IndexOf("<div>", html.IndexOf("<body>") + "<body>".Length) + "<div>".Length;
            if (startIndex > -1)
            {
                int length = html.LastIndexOf("</div>") - startIndex;
                if (length > -1)
                    html = html.Substring(startIndex, length);
            }
            if (!string.IsNullOrEmpty(error))
            {
                SyntaxHighlighter s = new SyntaxHighlighter("ASPX");
                error = s.GetParsedSourceCode(error, false);
            }

            return new Pair(html, error);
        }

        public override string GetCssStyle()
        {
            return base.GetCssStyle();
        }

        public override string GetCssStyle(bool useDesigntimeResourceUrl)
        {
            string css = string.Empty;
            if (string.IsNullOrEmpty(ExternalStyleSheet))
            {
                if (IconsMode == IconType.ImageSprites)
                {
                    css = ToolBarMode == ToolBarType.Advanced ? GetTemplateData(string.Format(
                        RootSkinFolder, SelectedSkin, "Css.editorimagespritesadvanced.css")) :
                           GetTemplateData(string.Format(
                                   RootSkinFolder, SelectedSkin, "Css.editorimagespritesbasic.css"));
                }
                else
                {
                    css = GetTemplateData(string.Format(
                         RootSkinFolder, SelectedSkin, "Css.editoricons.css"));
                }
                css = TransformCssImageUrls(css, useDesigntimeResourceUrl);
            }
            else if (DesignMode)
            {
                string path = Helper.MapPath(Host, ExternalStyleSheet, PathType.Physical);
                using (StreamReader sr = new StreamReader(path))
                    css = sr.ReadToEnd();
            }
            return css;
        }

        public Stream GetDictionaryFile()
        {
            return GetDictionaryFile(null);
        }

        public Stream GetDictionaryFile(DictionaryItem di)
        {
            if (di == null)
                di = SelectedDictionaryFile;
            string languageCode = di.Value;
            string dictionaryFileName = languageCode + ".dic";
            string filePath = string.Empty;
            Stream s = null;
            if (!string.IsNullOrEmpty(di.Path))
            {
                filePath = this.Page.MapPath(di.Path);
                StreamReader sr = new StreamReader(filePath, Encoding.UTF8);
                s = sr.BaseStream;
            }
            else
            {
                s = typeof(Editor).Assembly.GetManifestResourceStream(
                    Helper.GetManifestResourceName(dictionaryFileName,
                    ManifestResourceNamesCache));
            }
            return s;
        }

        public override string GetSharedCssStyle()
        {
            return base.GetSharedCssStyle();
        }

        public override string GetTreeViewCssStyle()
        {
            return base.GetTreeViewCssStyle();
        }

        public virtual bool IgnoredWordsLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;
            else
            {
                IgnoredWords = postedValue.Trim();
                return true;
            }
        }

        public virtual bool TextLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            string presentValue = Text;
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;

            Pair p = FixMarkup(postedValue, false);

            Text = (string)p.First;
            if (ElementsAllowed.Count > 0)
                Text = StripUnallowedHtml(Text);

            string innerText = StripMarkup(Text);
            int length = innerText.Length;
            TextChangedEventArgs args = null;
            if (MaxLength > 0)
            {
                if (length > MaxLength)
                {
                    args = new TextChangedEventArgs(Text, length);
                    OnMaxLengthReached(args);
                }
            }
            if (!presentValue.Equals(Text, StringComparison.Ordinal))
            {
                args = new TextChangedEventArgs(Text, length);
                OnTextChanged(args);
                return true;
            }
            return false;
        }

        public virtual bool ValidationRequestLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;
            else
            {
                ValidationMarkup = postedValue;
                return true;
            }
        }

        public virtual bool WordForSuggestionLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;
            else
            {
                WordForSuggestion = postedValue.Trim();
                return true;
            }
        }

        public virtual bool WordPastingCleanupLoadPostData(string postDataKey,
            NameValueCollection postCollection)
        {
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;
            else
            {
                WordCleanupMarkup = postedValue;
                return true;
            }
        }

        internal List<CallbackHandler> GetAsyncEvents()
        {
            //ToDO:toolBarset : validate the command property. make sure that it is unique, if not throw an error!
            List<CallbackHandler> handlerList = new List<CallbackHandler>();
            handlerList.Add(new CallbackHandler("inserttable", "TableDesignerRequest", TableDesignerLoadingMessage));
            handlerList.Add(new CallbackHandler("cellsdesigner", "CellsDesignerRequest", CellsDesignerLoadingMessage));
            handlerList.Add(new CallbackHandler("createlink", "HyperlinkRequest", HyperlinkDesignerLoadingMessage));
            handlerList.Add(new CallbackHandler("codehilighter", "CodeHighlighterRequest", CodeHilighterLoadingMessage));
            handlerList.Add(new CallbackHandler("wordcleanup", "WordPasteCleanupRequest", WordPasteCleanupLoadingMessage));
            handlerList.Add(new CallbackHandler("htmlview", "ValidationRequest", HtmlValidationMessage));
            handlerList.Add(new CallbackHandler("spell", "SpellCheckerRequest", SpellCheckerLoadingMessage));
            handlerList.Add(new CallbackHandler("selecteddictionary", "SelectedDictionary", SpellCheckingMessage));
            handlerList.Add(new CallbackHandler("wordsuggestion", "WordSuggestionRequest", WordSuggestionLoadingMessage));
            handlerList.Add(new CallbackHandler("codehilighting", "CodeHighlighting", CodeHighlightingMessage));
            handlerList.Add(new CallbackHandler("wordpastingcleanup", "WordPastingCleanup", WordPastingCleanupMessage));
            handlerList.Add(new CallbackHandler("csslist", "CssClassNamesListRequest", CssStyleMessage));
            handlerList.Add(new CallbackHandler("htmlviewhilight", "HtmlViewHighlightRequest", HtmlViewHilightMessage));
            handlerList.Add(new CallbackHandler("designview", "DesignViewValidationRequest", HtmlValidationMessage));
            if (RegisterAsyncPostBackSaveTrigger)
                handlerList.Add(new CallbackHandler("save", "Save", RichTextSavingMessage));
            handlerList.Add(new CallbackHandler("multifileuploader", "MultiFileUploaderRequest", MultiFileUploaderLoading));
            handlerList.Add(new CallbackHandler("filebrowser", "FileBrowserRequest", FileBrowserLoadingMessage));
            handlerList.Add(new CallbackHandler("fileupload", "FileUploadRequest", FileUploadingMessage));
            return handlerList;
        }

        internal virtual void OnCellsDesignerRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "CellDesigner.html");
            _webResponseData = this.GetTemplateData(templateName);
        }

        internal virtual void OnClassNameListRequest(EventArgs e)
        {
            _webResponseData = ToJsonString(CssClassNamesList);
        }

        internal virtual void OnCodeHighlighterRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "CodeHilighter.html");
            _webResponseData = this.GetTemplateData(templateName);
        }

        internal virtual void OnCodeHighlighting(EventArgs e)
        {
            if (CodeHilightText != string.Empty)
            {
                string[] parts = CodeHilightText.Split(new string[] { "$code$hilighter$sep$" }, StringSplitOptions.None);
                string source = parts[0];
                bool enableLineNumbering = bool.Parse(parts[1]);
                string language = parts[2];
                bool showLanguage = bool.Parse(parts[3]);
                string languageMarkup = string.Empty;
                SyntaxHighlighter s = new SyntaxHighlighter(language, new HtmlParser(),
                    enableLineNumbering, source);

                _webResponseData = s.GetParsedSourceCode(EnableSyntaxHighlighterInlineCss);

                if (showLanguage)
                    languageMarkup = string.Format(@"<h2>{0}</h2>", language);

                string html =
            @"<div class=""syntaxhighlighter"">
            {0}
            {1}
            <br style=""clear:both"" />
              </div>";
                _webResponseData = string.Format(html, languageMarkup, _webResponseData);
            }
        }

        internal virtual void OnFileUploaded(UploadedFileEventArgs e)
        {
            if (FileUploaded != null)
            {
                FileUploaded(this, e);
            }
            _webResponseData = ToJsonString(e);
        }

        internal virtual void OnFileUploadRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "FileUpload.html");
            _webResponseData = this.GetTemplateData(templateName).Replace("controlID", ClassName);
        }

        internal virtual void OnHtmlViewHighlightRequest(EventArgs e)
        {
            Pair p = FixMarkup(ValidationMarkup, false);
            string source = p.First.ToString();
            if (ElementsAllowed.Count > 0)
                source = StripUnallowedHtml(source);
            _webResponseData = GetASPXSyntaxHighlight(source, false);
        }

        internal virtual void OnHyperlinkRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "Hyperlink.html");
            _webResponseData = this.GetTemplateData(templateName);
        }

        internal virtual void OnMultiFilesUploaded(UploadedMultiFileEventArgs e)
        {
            if (MultiFilesUploaded != null)
            {
                MultiFilesUploaded(this, e);
            }
            _webResponseData = ToJsonString(e.PostedMultiFile);
        }

        internal virtual void OnMultiFileUploaderRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "MultiFileUploader.html");
            _webResponseData = this.GetTemplateData(templateName).Replace("controlID", ClassName);
        }

        internal virtual void OnSpellCheckerRequest(EventArgs e)
        {
            List<string> l = new List<string>();
            foreach (DictionaryItem di in Dictionaries)
            {
                l.Add(string.Format("{0}:{1}", di.Text, di.Value));
            }
            _webResponseData = string.Join(";", l.ToArray());
        }

        internal virtual void OnTableDesignerRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "TableDesigner.html");
            _webResponseData = this.GetTemplateData(templateName);
        }

        internal virtual void OnValidationRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "ErrorsLoggedMessage.html");
            Pair p = FixMarkup(ValidationMarkup, false);
            if (ElementsAllowed.Count > 0)
                p.First = StripUnallowedHtml(p.First.ToString());

            string errorLog = p.Second.ToString();
            string errorLoggedMessageDialog = string.Empty;
            if (errorLog != string.Empty && ErrorLogNotification)
                errorLoggedMessageDialog = this.GetTemplateData(templateName);
            _webResponseData = string.Format("{0}$Html$ErrorLog$Sep${1}$Html$ErrorLog$Sep${2}", p.First.ToString(), errorLog, errorLoggedMessageDialog);
        }

        internal virtual void OnWordPasteCleanupRequest(EventArgs e)
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "WordCleanup.html");
            _webResponseData = this.GetTemplateData(templateName);
        }

        internal virtual void OnWordPastingCleanup(EventArgs e)
        {
            Pair p = FixMarkup(WordCleanupMarkup, true);
            if (ElementsAllowed.Count > 0)
                p.First = StripUnallowedHtml(p.First.ToString());
            _webResponseData = p.First.ToString() + "$Html$ErrorLog$Sep$" + p.Second.ToString();
        }

        internal virtual void OnWordSuggestionRequest(EventArgs e)
        {
            if (!string.IsNullOrEmpty(WordForSuggestion))
            {
                string[] wordPair = WordForSuggestion.Split(new string[] { "$word$suggestion$sep$" }, StringSplitOptions.RemoveEmptyEntries);
                // 0 contains word, 1 contains id of span containing the word.
                _webResponseData = string.Join(";", GetSpellingSuggetions(wordPair[0]).ToArray());
                _webResponseData += "$word$suggestion$sep$" + wordPair[1];
            }
        }

        internal virtual void RegisterAsyncEvents(ref ScriptControlDescriptor descriptor)
        {
            List<CallbackHandler> listHandler = GetAsyncEvents();
            string json = ToJsonString(listHandler);
            descriptor.AddScriptProperty("callbacks", json);
        }

        internal virtual void SetAutoPromptMultiFileUploadDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("autoPromptMultiFileUpload", AutoPromptMultiFileUpload);
        }

        internal virtual void SetAutoResolveToAbsolutePathDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("autoResolveToAbsolutePath", AutoResolveToAbsolutePath);
        }

        internal virtual void SetAutoSwitchTextDirectionDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("autoSwitchTextDirection", AutoSwitchTextDirection);
        }

        internal virtual void SetClientSideEventsDescriptor(ref ScriptControlDescriptor descriptor)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("toolBarItemClick", ClientSideToolBarItemClick);
            dic.Add("tabItemClick", ClientSideTabItemClick);
            dic.Add("toolBarOptionItemClick", ClientSideToolBarOptionsItemClick);
            dic.Add("popupCloseButton", ClientSidePopupCloseButtonClick);
            dic.Add("colorSelect", ClientSideColorSelect);
            dic.Add("fontsizeSelect", ClientSideFontSizeDropDownSelect);
            dic.Add("maxLengthReached", ClientSideMaxLengthReached);
            dic.Add("fontsizeClose", ClientSideFontSizeDropDownClose);
            dic.Add("fontnameSelect", ClientSideFontNameDropDownSelect);
            dic.Add("fontnameClose", ClientSideFontNameDropDownClose);
            dic.Add("formatBlockSelect", ClientSideFormatBlockDropDownSelect);
            dic.Add("formatBlockClose", ClientSideFormatBlockDropDownClose);
            dic.Add("saving", ClientSideSaving);
            dic.Add("saved", ClientSideSaved);

            foreach (string eventName in dic.Keys)
            {
                string val = dic[eventName];
                if (!string.IsNullOrEmpty(val))
                    descriptor.AddEvent(eventName, val);
            }
        }

        internal virtual void SetColorPickerIdDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("colorPickerId", EmbeddedColorPicker.ClientID);
        }

        internal virtual void SetCssClassIdentifiersDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            if (string.IsNullOrEmpty(ExternalStyleSheet))
                EnsureDefaultClassIdentifier();//make sure the default file is set :-)
            descriptor.AddProperty("cssClassIdentifiers", string.Join(",", CssClassIdentifiers));
        }

        internal virtual void SetDataFileUrlDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            string dataFileUrl = Helper.GetValidWebResourceUrl(this,
                Helper.GetManifestResourceName("HttpFiles.data.htm",
                ManifestResourceNamesCache));
            descriptor.AddProperty("dataFileUrl", dataFileUrl);
        }

        internal virtual void SetDirectionDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("direction", Direction);
        }

        internal virtual void SetDisabledButtonBackColorDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("disabledButtonBackColor", ColorTranslator.ToHtml(DisabledButtonBackColor));
        }

        internal virtual void SetDisabledButtonBorderColorDescriptorr(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("disabledButtonBorderColor", ColorTranslator.ToHtml(DisabledButtonBorderColor));
        }

        internal virtual void SetDisabledButtonTransparencyDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("disabledButtonTransparency", DisabledButtonTransparency);
        }

        internal virtual void SetDisabledToolBarShaderColorDescriptor(ref ScriptControlDescriptor descriptor)
        {
            if (DisabledToolBarShaderColor != Color.Empty)
                descriptor.AddProperty("toolBarShadeColor", ColorTranslator.ToHtml(DisabledToolBarShaderColor));
        }

        internal virtual void SetDropDownListEffectDurationDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("dropDownListEffectDuration", DropDownListEffectDuration);
        }

        internal virtual void SetEnableCssListDescriptor(ref ScriptControlDescriptor descriptor)
        {
            bool cssListEnabled = (CssClassNamesList.Count > 0);
            descriptor.AddProperty("cssListEnabled", cssListEnabled);
        }

        internal virtual void SetEnableDictionaryDescriptor(ref ScriptControlDescriptor descriptor)
        {
            bool dictionaryEnabled = (Dictionaries.Count > 0);
            descriptor.AddProperty("dictionaryEnabled", dictionaryEnabled);
        }

        internal virtual void SetEnableDropDownListEffectsDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("enableDropDownListEffects", EnableDropDownListEffects);
        }

        internal virtual void SetEnableFileBrowserDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("enableFileBrowser", EnableFileBrowser);
        }

        internal virtual void SetEnableFileUploadDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("enableFileUpload", EnableFileUpload);
        }

        internal virtual void SetEnableToolBarFloatDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("enableToolBarFloat", EnableToolBarFloat);
        }

        internal virtual void SetExternalStyleSheetDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("externalStyleSheet", ExternalStyleSheet);
        }

        internal virtual void SetExternalStyleSheetReferencesDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("externalStyleSheetReferences", string.Join(",", ExternalStyleSheetReferences));
        }

        internal virtual void SetExternalStyleSheetsDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("externalStyleSheets", string.Join(",", ExternalStyleSheets));
        }

        internal virtual void SetFileRemoveImageUrlDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            string url = Helper.GetBackgroundImageUrl(this,
                string.Format(RootImageSkinFolder, SelectedSkin, "cancel.gif"));
            descriptor.AddProperty("fileRemoveImageUrl", url);
        }

        internal virtual void SetFileUploadingMessageDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("fileUploadingMessage", FileUploadingMessage);
        }

        internal virtual void SetFileUploadMimeFilterDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("fileUploadMimeFilter", FileUploadMimeFilter);
        }

        internal virtual void SetFontNamesDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            if (FontNames != null && FontNames.Length > 0)
                descriptor.AddProperty("fontNames", FontNames);
        }

        internal virtual void SetFormatBlockLabelDescriptor(ref ScriptControlDescriptor descriptor)
        {
            string key1 = "formatBlockLabel";
            string properties = "{" + string.Format("p:\"{0}\",h:\"{1}\",pre:\"{2}\"", this.Paragraph, this.Heading, this.Preformatted) + "}";
            descriptor.AddScriptProperty(key1, properties);
        }

        internal virtual void SetFormElementIdDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("formElementId", Page.Form.ClientID);
        }

        internal virtual void SetGlobalClassNameDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("className", ClassName);
        }

        internal virtual void SetHeightDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("height", Height.ToString());
        }

        internal virtual void SetIconsModeDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("mode", IconsMode);
        }

        internal virtual void SetImagePickerIdDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("imagePickerId", EmbeddedImagePicker.ClientID);
        }

        internal virtual void SetMaxLengthDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            if (MaxLength > 0)
                descriptor.AddProperty("maxLength", MaxLength);
        }

        internal virtual void SetMultiFileUploaderProgressDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("multiFileUploaderProgress", MultiFileUploaderProgress);
        }

        internal virtual void SetMultiFileUploadMimeFilterDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("multiFileUploadMimeFilter", MultiFileUploadMimeFilter);
        }

        internal virtual void SetMultiFileUploadRequiredMessageDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("fileUploadRequiredMessage", MultiFileUploadRequiredMessage);
        }

        internal virtual void SetPostbackAllFormDataDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("postbackAllFormData", PostbackAllFormData);
        }

        internal virtual void SetShaderColorDescriptor(ref ScriptControlDescriptor descriptor)
        {
            if (ShaderColor != Color.Empty)
                descriptor.AddProperty("shaderColor", ColorTranslator.ToHtml(ShaderColor));
        }

        internal virtual void SetShaderOpacityDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("shaderOpacity", ShaderOpacity);
        }

        internal virtual void SetSuggestionListHeaderTitleDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("suggestionListHeaderTitle", SuggestionListHeaderTitle);
        }

        internal virtual void SetSuggestionListIgnoreLabelDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("ignoreLabel", SuggestionListIgnoreLabel);
        }

        internal virtual void SetTabButtonsDescriptor(ref ScriptControlDescriptor descriptor)
        {
            TabCollection tc = new TabCollection();
            for (int num1 = 0; num1 < this.Tabs.Count; num1++)
            {
                TabItem ti = this.Tabs[num1] as TabItem;
                if (IconsMode == IconType.ImageSprites)
                {
                    tc.Add(new TabItem
                    {
                        MarginLeft = ti.MarginLeft,
                        Command = ti.Command,
                        ToolTip = ti.ToolTip,
                        Width = ti.Width,
                        Enabled = ti.Enabled
                    });
                }
                else
                {
                    string iconUrl = string.Empty;
                    if (!string.IsNullOrEmpty(ti.Icon))
                    {
                        iconUrl = string.Format(TabsImageSkinFolder,
                                             SelectedSkin, ti.Icon);
                        if (IsCustomSkin)
                            iconUrl = Helper.EnsurePhysicalPath(iconUrl);
                        else if (IsEmbeddedResource(ti.Icon))
                            iconUrl = Helper.GetBackgroundImageUrl(this, iconUrl);
                        else
                            iconUrl = ResolveUrl(ti.Icon);
                    }
                    tc.Add(new TabItem
                    {
                        MarginLeft = ti.MarginLeft,
                        Command = ti.Command,
                        ToolTip = ti.ToolTip,
                        Width = ti.Width,
                        Enabled = ti.Enabled,
                        Break = ti.Break,
                        Icon = iconUrl
                    });
                }
            }
            descriptor.AddScriptProperty("tabCollection", ToJsonString(tc));
        }

        internal virtual void SetTabLeftBorderImageDescriptor(ref ScriptControlDescriptor descriptor)
        {
            string imageUrl = string.Empty;
            if (!string.IsNullOrEmpty(TabLeftBorderImage))
            {
                string resourceName = string.Format(TabsImageSkinFolder, SelectedSkin,
                    TabLeftBorderImage);

                imageUrl = Helper.GetBackgroundImageUrl(this, resourceName);
            }
            descriptor.AddProperty("tabLeftBorderImage", imageUrl);
        }

        internal virtual void SetToolBarButtonsDescriptor(ref ScriptControlDescriptor descriptor)
        {
            ToolBarCollection tbc = new ToolBarCollection();
            for (int num1 = 0; num1 < this.ToolBars.Count; num1++)
            {
                ToolBarSet tbs = this.ToolBars[num1] as ToolBarSet;
                ToolBarSet bars = new ToolBarSet();
                foreach (ToolBarItem tbi in tbs.Items)
                {
                    if (IconsMode == IconType.ImageSprites)
                    {
                        bars.Items.Add(new ToolBarItem
                        {
                            MarginLeft = tbi.MarginLeft,
                            Name = tbi.Name,
                            ToolTip = tbi.ToolTip,
                            Enabled = tbi.Enabled,
                            GroupName = tbi.GroupName,
                            ToggleEnabled = tbi.ToggleEnabled
                        });
                    }
                    else
                    {
                        string iconUrl = string.Empty;
                        if (!string.IsNullOrEmpty(tbi.Icon))
                        {
                            iconUrl = string.Format(ToolBarsImageSkinFolder, SelectedSkin, tbi.Icon);
                            if (IsCustomSkin)
                                iconUrl = Helper.EnsurePhysicalPath(iconUrl);
                            else if (IsEmbeddedResource(tbi.Icon))
                                iconUrl = Helper.GetBackgroundImageUrl(this, iconUrl);
                            else
                                iconUrl = ResolveUrl(tbi.Icon);
                        }
                        bars.Items.Add(new ToolBarItem
                        {
                            MarginLeft = tbi.MarginLeft,
                            Name = tbi.Name,
                            ToolTip = tbi.ToolTip,
                            Enabled = tbi.Enabled,
                            Icon = iconUrl,
                            Break = tbi.Break,
                            GroupName = tbi.GroupName,
                            ToggleEnabled = tbi.ToggleEnabled
                        });
                    }
                }
                tbc.Add(bars);

                string leftBorderImage = string.Format(ToolBarSetImageSkinFolder,
                   SelectedSkin, tbs.LeftBorderImage);

                string optionsImage = string.Format(ToolBarSetImageSkinFolder,
                    SelectedSkin, tbs.OptionsImage);

                if (IsCustomSkin)
                    leftBorderImage = Helper.EnsurePhysicalPath(leftBorderImage);
                else if (IsEmbeddedResource(tbs.LeftBorderImage))
                    leftBorderImage = Helper.GetBackgroundImageUrl(this, leftBorderImage);
                else
                    leftBorderImage = ResolveUrl(tbs.LeftBorderImage);

                if (IsCustomSkin)
                    optionsImage = Helper.EnsurePhysicalPath(optionsImage);
                else if (IsEmbeddedResource(tbs.OptionsImage))
                    optionsImage = Helper.GetBackgroundImageUrl(this, optionsImage);
                else
                    optionsImage = ResolveUrl(tbs.OptionsImage);

                bars.LeftBorderImage = leftBorderImage;
                bars.OptionsImage = optionsImage;
            }
            string json = ToJsonString(tbc);
            descriptor.AddScriptProperty("toolBarCollection", json);
        }

        internal virtual void SetToolBarContainerIdDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("toolbarContainerId", ToolBarContainerId);
        }

        internal virtual void SetToolBarSeparatorImageDescriptor(ref ScriptControlDescriptor descriptor)
        {
            string resourceName = string.Format(RootImageSkinFolder, SelectedSkin,
                           ToolBarSeparatorImage);

            string imageUrl = Helper.GetBackgroundImageUrl(this,
                            resourceName);

            descriptor.AddProperty("toolBarSeparatorImage", imageUrl);
        }

        internal virtual void SetTransparentImageUrlDescriptor(ref  ScriptControlDescriptor descriptor)
        {
            string url = string.Format("Typps.Resources.Skins.{0}.Images.Shared.transparent.gif", SelectedSkin);
            if (IsCustomSkin)
                url = Helper.GetPhysicalPathByResourceNamespace(url, this);

            string imgUrl = Helper.GetBackgroundImageUrl(this, url);
            descriptor.AddProperty("transparentImageUrl", imgUrl);
        }

        internal virtual void SetUniqueIdDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("uniqueId", this.UniqueID);
        }

        internal virtual void SetUpdatePanelProgressIdDescriptor(ref ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("updatePanelProgressId", EmbeddedUpdatePanelProgress.ClientID);
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            // override to disable
            if (this.ID != null)
                writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
            if (this.ClassName != string.Empty)
                writer.AddAttribute("class", ClassName);
            if (!DesignMode && IsBrowserUpLevel)
                writer.AddStyleAttribute(HtmlTextWriterStyle.Visibility, "hidden");

            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, Width.ToString());

            string accessKey = this.AccessKey;
            if (accessKey.Length > 0)
                writer.AddAttribute(HtmlTextWriterAttribute.Accesskey, accessKey);
            if (!this.Enabled)
                writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
        }

        protected override void CreateChildControls()
        {
            if (cs == null && Page != null)
                cs = Page.ClientScript;

            base.CreateChildControls();

            if (IsBrowserUpLevel || DesignMode)
            {
                EnsureDefaultClassIdentifier();
                SetCssClassNamesList();
                SetToolBarDefaults();
                SetTabDefaults();

                CreateMarkup();
                SetDictionaryDefaults();
            }
            else
            {
                DownLevelRender();
            }
            CreateImagePicker();
            CreateColorPicker();
            if ((!IsDesignMode && !IsCallback) && (this.Page != null && this.Page.Form != null))
                this.Page.Form.Enctype = "multipart/form-data";
        }

        protected override string GetLocalizedText(string key)
        {
            return base.GetLocalizedText(key);
        }

        protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Typps.Editor", this.ClientID);
            if (DesignMode)
                return new ScriptDescriptor[] { descriptor };
            SetToolBarButtonsDescriptor(ref descriptor);
            SetToolBarContainerIdDescriptor(ref descriptor);
            SetTabButtonsDescriptor(ref descriptor);
            SetFormatBlockLabelDescriptor(ref descriptor);
            SetGlobalClassNameDescriptor(ref descriptor);
            SetShaderColorDescriptor(ref descriptor);
            SetShaderOpacityDescriptor(ref descriptor);
            SetDisabledToolBarShaderColorDescriptor(ref descriptor);
            SetSuggestionListIgnoreLabelDescriptor(ref descriptor);
            SetSuggestionListHeaderTitleDescriptor(ref descriptor);
            RegisterAsyncEvents(ref descriptor);
            SetClientSideEventsDescriptor(ref descriptor);
            SetEnableCssListDescriptor(ref descriptor);
            SetEnableDictionaryDescriptor(ref descriptor);
            SetEnableToolBarFloatDescriptor(ref descriptor);
            SetUniqueIdDescriptor(ref descriptor);
            SetUpdatePanelProgressIdDescriptor(ref descriptor);
            SetDisabledButtonBackColorDescriptor(ref descriptor);
            SetDisabledButtonTransparencyDescriptor(ref descriptor);
            SetDisabledButtonBorderColorDescriptorr(ref descriptor);
            SetToolBarSeparatorImageDescriptor(ref descriptor);
            if (!string.IsNullOrEmpty(TabLeftBorderImage))
                SetTabLeftBorderImageDescriptor(ref descriptor);
            SetIconsModeDescriptor(ref descriptor);
            SetImagePickerIdDescriptor(ref descriptor);
            SetColorPickerIdDescriptor(ref descriptor);
            SetFormElementIdDescriptor(ref descriptor);
            SetPostbackAllFormDataDescriptor(ref descriptor);
            SetCssClassIdentifiersDescriptor(ref descriptor);
            SetExternalStyleSheetDescriptor(ref descriptor);
            SetExternalStyleSheetsDescriptor(ref descriptor);
            SetExternalStyleSheetReferencesDescriptor(ref descriptor);
            SetDataFileUrlDescriptor(ref descriptor);
            SetDirectionDescriptor(ref descriptor);
            SetHeightDescriptor(ref descriptor);
            SetTransparentImageUrlDescriptor(ref descriptor);
            SetAutoSwitchTextDirectionDescriptor(ref descriptor);
            SetAutoResolveToAbsolutePathDescriptor(ref descriptor);
            SetMultiFileUploadRequiredMessageDescriptor(ref descriptor);
            SetAutoPromptMultiFileUploadDescriptor(ref descriptor);
            SetMultiFileUploaderProgressDescriptor(ref descriptor);
            SetFileRemoveImageUrlDescriptor(ref descriptor);
            SetFileUploadingMessageDescriptor(ref descriptor);
            SetEnableFileBrowserDescriptor(ref descriptor);
            SetEnableFileUploadDescriptor(ref descriptor);
            SetFileUploadMimeFilterDescriptor(ref descriptor);
            SetMultiFileUploadMimeFilterDescriptor(ref descriptor);
            SetEnableDropDownListEffectsDescriptor(ref descriptor);
            SetDropDownListEffectDurationDescriptor(ref descriptor);
            SetMaxLengthDescriptor(ref descriptor);

            if (FontNames != null && FontNames.Length > 0)
                SetFontNamesDescriptor(ref descriptor);
            return new ScriptDescriptor[] { descriptor };
        }

        protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            if (cs == null) return null;
            bool isDebugMode = SM.ScriptMode == ScriptMode.Debug;
            string script1 = !isDebugMode ? "ClientScripts.startup.min.js" : "ClientScripts.startup.js";
            string script2 = !isDebugMode ? "ClientScripts.modalpopup.min.js" : "ClientScripts.modalpopup.js";
            string script3 = !isDebugMode ? "ClientScripts.editor.min.js" : "ClientScripts.editor.js";
            string script4 = !isDebugMode ? "ClientScripts.spryeffects.min.js" : "ClientScripts.spryeffects.js";
            ScriptReference reference1 = new ScriptReference();
            reference1.Path = cs.GetWebResourceUrl(typeof(ResourceDummy),
                Helper.GetManifestResourceName(script1,
                ManifestResourceNamesCache, isDebugMode));

            ScriptReference reference2 = new ScriptReference();
            reference2.Path = cs.GetWebResourceUrl(typeof(ResourceDummy),
                Helper.GetManifestResourceName(script2,
                ManifestResourceNamesCache, isDebugMode));

            ScriptReference reference3 = new ScriptReference();
            reference3.Path = cs.GetWebResourceUrl(typeof(Editor),
                Helper.GetManifestResourceName(script3,
                ManifestResourceNamesCache, isDebugMode));

            ScriptReference reference4 = new ScriptReference();
            reference4.Path = cs.GetWebResourceUrl(typeof(ResourceDummy),
                Helper.GetManifestResourceName(script4,
                ManifestResourceNamesCache, isDebugMode));

            return new ScriptReference[] { reference1, reference2, reference3, reference4 };
        }

        protected override string GetTemplateData(string templateName)
        {
            return base.GetTemplateData(templateName);
        }

        protected override void InitializeCSSRegistration()
        {
            base.InitializeCSSRegistration();
        }

        protected override void LoadViewState(object state)
        {
            if (state != null)
            {
                object[] states = (object[])state;
                base.LoadViewState(states[0]);
                ((IStateManager)ToolBars).LoadViewState(states[1]);
                ((IStateManager)Dictionaries).LoadViewState(states[2]);
                ((IStateManager)Tabs).LoadViewState(states[3]);
                ((IStateManager)CssClassNamesList).LoadViewState(states[4]);
            }
        }

        protected virtual void OnFileBrowserRequest(EventArgs e)
        {
            if (BrowseFilesServerRequest != null)
                BrowseFilesServerRequest(this, e);
            if (FileGalleryNode == null) return;

            HTreeView tv = new HTreeView(ClientID + "_treeview", ClassName + " htreeview");
            if (FileGalleryNode.ChildNodes.Count > 0)
                tv.Nodes.Add(FileGalleryNode);

            string treeview = tv.Render();
            string templateName = string.Format(RootTemplateSkinFolder,
                SelectedSkin, "FileBrowser.html");
            _webResponseData = this.GetTemplateData(templateName).Replace("controlID", ClassName);
            _webResponseData = _webResponseData.Replace("#fileExplorer#", treeview);
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!this.DesignMode)
            {
                CultureInfo ci = CultureInfo.CurrentCulture;
                if (ci.TextInfo.IsRightToLeft)
                    Direction = Dir.RTL;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            EnsureChildControls();
            cs = Page.ClientScript;
            if (!this.DesignMode)
            {
                EnsureScriptManager();
                if (!IsCallback)
                    TextLoadPostData(this.UniqueID + "$editortext", Context.Request.Form);

                if (IsCallback)
                    RaiseCallbackEvent();
                if (IsMultiFileUploading)
                {
                    if (Context.Request.Files.Count > 0)
                        RaiseMultiFileUploaded();
                }
                if (IsFileUploading)
                {
                    if (Context.Request.Files.Count > 0)
                    {
                        string argument = Context.Request.Form[Page.postEventArgumentID];
                        FileTransmitInfo fti = FromJson<FileTransmitInfo>(argument);
                        UploadedFileEventArgs args = new UploadedFileEventArgs(
                            fti.Id, Context.Request.Files[fti.Id]);
                        OnFileUploaded(args);
                    }
                }
            }
            if (IsBrowserUpLevel)
                RegisterOnSubmit();
        }

        protected virtual void OnMaxLengthReached(TextChangedEventArgs e)
        {
            if (MaxLengthReached != null)
                MaxLengthReached(this, e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (Tabs.Count == 0 && _tabList != null)
            {
                _tabList.Style["display"] = "none";
                _tabContainer.Style["display"] = "none";
            }
            if (_enumerateFileGallery)
                OnFileBrowserRequest(new EventArgs());

            if (IsCallback) return;
            RenderStylesAndScripts();
        }

        protected virtual void OnSaveClick(TextSavingEventArgs e)
        {
            if (SaveClick != null)
                SaveClick(this, e);
            _webResponseData = ToJsonString(e);
        }

        protected virtual void OnSelectedDictionary(EventArgs e)
        {
            if (SelectedDictionary != null)
                SelectedDictionary(this, e);
        }

        protected virtual void OnTextChanged(TextChangedEventArgs e)
        {
            if (TextChanged != null)
                TextChanged(this, e);
        }

        protected override void OnUnload(EventArgs e)
        {
            //close resourcemanager here!
            base.OnUnload(e);
            if (IsMultiFileUploading || IsFileUploading)
            {
                ResponseWrite(_webResponseData, "text/plain");
            }
            else if (IsCallback && !string.IsNullOrEmpty(CallbackArgument))
            {
                ResponseWrite(string.Format("{0}$callbackdata${1}$sep${2}",
                    CallbackArgument, this.ClientID, _webResponseData), "text/plain");
            }
        }

        protected override string QueryStringData(CssFile cssFileToRegister)
        {
            bool formatStyleSheet = SM.ScriptMode == ScriptMode.Debug;
            StringBuilder queryStrings = new StringBuilder(10);
            queryStrings.AppendFormat("&ctl={0}", (int)ControlName.Editor);
            queryStrings.AppendFormat("&s={0}", (int)Skin);
            queryStrings.AppendFormat("&cs={0}", CustomSkin);
            queryStrings.AppendFormat("&csf={0}", CustomSkinFolder);
            queryStrings.AppendFormat("&im={0}", (int)IconsMode);
            queryStrings.AppendFormat("&dir={0}", (int)Direction);
            queryStrings.AppendFormat("&cc={0}", ClassName);
            queryStrings.AppendFormat("&tbm={0}", (int)ToolBarMode);
            queryStrings.AppendFormat("&fcss={0}", formatStyleSheet);
            queryStrings.AppendFormat("&cssfile={0}", cssFileToRegister);

            return queryStrings.ToString();
        }

        protected override void RegisterEmbededCss()
        {
            base.RegisterEmbededCss();
        }

        protected override void RegisterExternalStyleSheetReferences()
        {
            base.RegisterExternalStyleSheetReferences();
        }

        protected override void RenderStylesAndScripts()
        {
            base.RenderStylesAndScripts();
        }

        protected override void ResetCollectionsAndStyles()
        {
            ToolBars.Clear();
            _defaultItems.Clear();
            Tabs.Clear();
            CssClassNamesList.Clear();
            Dictionaries.Clear();
            RecreateChildControls();
        }

        protected override object SaveViewState()
        {
            foreach (KeyValuePair<string, string> kvp in _defaultItems)
            {
                //defaults do not require viewstate.
                object value = ViewState[kvp.Key];
                if (value != null)
                    if (kvp.Value.Equals(value.ToString()))
                        ViewState.Remove(kvp.Key);
            }
            object[] states = new object[5];
            states[0] = base.SaveViewState();
            states[1] = (_toolBars != null) ? ((IStateManager)_toolBars).SaveViewState() : null;
            states[2] = (_dictionaries != null) ? ((IStateManager)_dictionaries).SaveViewState() : null;
            states[3] = (_tabs != null) ? ((IStateManager)_tabs).SaveViewState() : null;
            states[4] = (_cssClassNamesList != null) ? ((IStateManager)_cssClassNamesList).SaveViewState() : null;
            return states;
        }

        protected override void TrackViewState()
        {
            base.TrackViewState();
            if (_toolBars != null)
                ((IStateManager)_toolBars).TrackViewState();
            if (_dictionaries != null)
                ((IStateManager)_dictionaries).TrackViewState();
            if (_tabs != null)
                ((IStateManager)_tabs).TrackViewState();
            if (_cssClassNamesList != null)
                ((IStateManager)_cssClassNamesList).TrackViewState();
        }

        protected override string TransformCssImageUrls(string css, bool useDesigntimeResourceUrl)
        {
            return base.TransformCssImageUrls(css, useDesigntimeResourceUrl);
        }

        void CreateColorPicker()
        {
            HtmlGenericControl container = new HtmlGenericControl("li");
            container.Style["display"] = "none";
            container.Visible = IsBrowserUpLevel;

            EmbeddedColorPicker.ID = "colorpicker";

            EmbeddedColorPicker.UpdatePanelProgressId = EmbeddedUpdatePanelProgress.ClientID;
            EmbeddedColorPicker.ManuallyInitialize = true;

            if (Skin != SkinNames.Classic && EmbeddedColorPicker.Skin == SkinNames.Classic)
                EmbeddedColorPicker.Skin = Skin;

            if (!string.IsNullOrEmpty(CustomSkinFolder) && string.IsNullOrEmpty(EmbeddedColorPicker.CustomSkinFolder))
                EmbeddedColorPicker.CustomSkinFolder = CustomSkinFolder;

            if (CustomSkin != "None" && EmbeddedColorPicker.CustomSkin == "None")
                EmbeddedColorPicker.CustomSkin = CustomSkin;

            if (PostbackAllFormData)
                EmbeddedColorPicker.PostbackAllFormData = PostbackAllFormData;

            if (!string.IsNullOrEmpty(ExternalStyleSheet) ||
               !string.IsNullOrEmpty(EmbeddedColorPicker.ExternalStyleSheet))
                EmbeddedColorPicker.RegisterCSS = false;

            this.Controls.Add(container);
            container.Controls.Add(EmbeddedColorPicker);
        }

        private void CreateDivContainers(Control container)
        {
            HtmlGenericControl hgc1 = new HtmlGenericControl("div");
            hgc1.ID = "noneditablehtml";
            hgc1.Style["display"] = "none";
            hgc1.Attributes.Add("class", ClassName + "-htmlviewcolorhilight");
            hgc1.Style["width"] = "100%";
            hgc1.Style["margin"] = "0px";
            hgc1.Style["padding"] = "0px";
            hgc1.Style["overflow"] = "auto";
            container.Controls.Add(hgc1);

            HtmlGenericControl hgc2 = new HtmlGenericControl("div");
            hgc2.ID = "warningslog";
            hgc2.Style["display"] = "none";
            hgc2.Attributes.Add("class", ClassName + "-warningslog");
            hgc2.Style["width"] = "100%";
            hgc2.Style["overflow"] = "auto";
            container.Controls.Add(hgc2);
        }

        void CreateImagePicker()
        {
            HtmlGenericControl container = new HtmlGenericControl("li");
            container.Style["display"] = "none";
            container.Visible = IsBrowserUpLevel;
            this.Controls.Add(container);
            container.Controls.Add(EmbeddedImagePicker);

            EmbeddedImagePicker.ID = "imagepicker";

            EmbeddedImagePicker.UpdatePanelProgressId = EmbeddedUpdatePanelProgress.ClientID;
            EmbeddedImagePicker.ManuallyInitialize = true;

            if (Skin != SkinNames.Classic && EmbeddedImagePicker.Skin == SkinNames.Classic)
                EmbeddedImagePicker.Skin = Skin;

            if (!string.IsNullOrEmpty(CustomSkinFolder) && string.IsNullOrEmpty(EmbeddedImagePicker.CustomSkinFolder))
                EmbeddedImagePicker.CustomSkinFolder = CustomSkinFolder;

            if (CustomSkin != "None" && EmbeddedImagePicker.CustomSkin == "None")
                EmbeddedImagePicker.CustomSkin = CustomSkin;

            if (PostbackAllFormData)
                EmbeddedImagePicker.PostbackAllFormData = PostbackAllFormData;

            if (!string.IsNullOrEmpty(ExternalStyleSheet) ||
                !string.IsNullOrEmpty(EmbeddedImagePicker.ExternalStyleSheet))
                EmbeddedImagePicker.RegisterCSS = false;
        }

        private void CreateInputFields(Control container)
        {
            _textBoxHtmlContainer = new TextBoxNoEncode();
            _textBoxHtmlContainer.ID = "editortext";
            _textBoxHtmlContainer.EnableViewState = EnableViewStateOnRichText;
            _textBoxHtmlContainer.TextMode = TextBoxMode.MultiLine;
            _textBoxHtmlContainer.CssClass = ClassName + "-htmlview";// the same as the iframe
            _textBoxHtmlContainer.Style["display"] = "none";
            container.Controls.Add(_textBoxHtmlContainer);
            HiddenField hf2 = new HiddenField();
            hf2.ID = "ignorewords";
            container.Controls.Add(hf2);
            HiddenField hf3 = new HiddenField();
            hf3.ID = "displayspellingcompletemessage";
            container.Controls.Add(hf3);
            HiddenField hf4 = new HiddenField();
            hf4.ID = "properties";
            hf4.Value = string.Empty; // always reset it. we are collecting the value from the forms collection!
            container.Controls.Add(hf4);
        }

        private void CreateMarkup()
        {
            string id = string.Empty;
            HtmlGenericControl toolbar = null;
            HtmlGenericControl toolBarContainer = null;
            bool isDetachableToolBar = !string.IsNullOrEmpty(ToolBarContainerId);
            if (EnableToolBarFloat)
            {
                toolBarContainer = new HtmlGenericControl("div");
                toolBarContainer.ID = "floatingToolBar";
                toolBarContainer.Attributes.Add("class", ClassName + "-floatingtoolbar");
                toolBarContainer.Style["visibility"] = "hidden";
                toolBarContainer.Style["display"] = "none";
                if (!IsIE6AndBelow)
                    toolBarContainer.Style["position"] = "fixed";
                else
                    toolBarContainer.Style["position"] = "absolute";
                toolBarContainer.Style["z-index"] = "0";
                toolBarContainer.Style["left"] = "0px";
                toolBarContainer.Style["top"] = "0px";
                toolBarContainer.Style["padding-bottom"] = "5px";
                toolBarContainer.Style["padding-top"] = "0px";
                toolBarContainer.Style["margin"] = "0px";
            }
            if (EnableToolBarFloat || isDetachableToolBar)
            {
                toolbar = new HtmlGenericControl("ul");
                toolbar.ID = "toolbar";
                toolbar.Style["list-style-type"] = "none";
                if (isDetachableToolBar)
                    toolbar.Style["visibility"] = "hidden";
                toolbar.Style["margin"] = "0px";
                toolbar.Style["padding"] = "0px";
                toolbar.Style["float"] = "left";
                if (EnableToolBarFloat)
                    toolBarContainer.Controls.Add(toolbar);
            }

            if (this.ToolBars.Count > 0)
            {
                for (int num1 = 0; num1 < this.ToolBars.Count; num1++)
                {
                    ToolBarSet tbs = this.ToolBars[num1] as ToolBarSet;
                    HtmlGenericControl li1 = new HtmlGenericControl("li");
                    li1.ID = num1.ToString();
                    li1.Attributes.Add("class", string.Format("{0}-{1}", ClassName, num1));
                    li1.Style["float"] = (Direction == Dir.LTR) ? "left" : "right";

                    if (EnableToolBarFloat || isDetachableToolBar)
                        toolbar.Controls.Add(li1);
                    else
                        this.Controls.Add(li1);

                    if (DesignMode && IconsMode == IconType.Icons)
                    {
                        HtmlGenericControl div = new HtmlGenericControl("div");
                        div.Style["float"] = "left";
                        li1.Controls.Add(div);
                        string leftBorderImage = string.Empty;
                        if (!string.IsNullOrEmpty(tbs.LeftBorderImage))
                        {
                            if (IsCustomSkin || IsEmbeddedResource(tbs.LeftBorderImage))
                                leftBorderImage = CreatePath(string.Format(ToolBarSetImageSkinFolder, SelectedSkin, tbs.LeftBorderImage));
                            else
                                leftBorderImage = Helper.MapPath(Host, tbs.LeftBorderImage, PathType.Physical);
                        }

                        string optionsImage = string.Empty;
                        if (!string.IsNullOrEmpty(tbs.OptionsImage))
                        {
                            optionsImage = string.Format(ToolBarSetImageSkinFolder, SelectedSkin,
                           tbs.OptionsImage);

                            if (IsCustomSkin || IsEmbeddedResource(tbs.OptionsImage))
                                optionsImage = CreatePath(string.Format(ToolBarSetImageSkinFolder, SelectedSkin, tbs.OptionsImage));
                            else
                                optionsImage = Helper.MapPath(Host, tbs.OptionsImage, PathType.Physical);
                        }
                        CreateToolBarIcons(leftBorderImage, optionsImage, tbs, div);
                    }
                }
            }

            if (EnableToolBarFloat)
            {
                HtmlGenericControl closeButtonContainer = new HtmlGenericControl("li");
                closeButtonContainer.Style["float"] = (Direction == Dir.LTR) ? "right" : "left";

                HtmlAnchor closeButton = new HtmlAnchor();
                closeButton.ID = "floatingToolBarCloseButton";
                closeButton.Attributes.Add("title", FloatingToolBarCloseTooltip);
                closeButton.Attributes.Add("class", "tristateclosebutton16x48");
                closeButton.Style["float"] = "right";
                closeButton.HRef = "javascript:void(0);";
                closeButtonContainer.Controls.Add(closeButton);
                toolbar.Controls.Add(closeButtonContainer);
            }

            HtmlGenericControl li3 = new HtmlGenericControl("li");
            li3.ID = "designarea";
            li3.Attributes.Add("class", ClassName + "-designarea");
            li3.Style["float"] = (Direction == Dir.LTR) ? "left" : "right";
            this.Controls.Add(li3);

            CreateUpdatePanelProgress(li3);
            CreateInputFields(li3);// insert the textarea and all hiddenfields.
            if (!DesignMode)
                CreateDivContainers(li3);// insert all divs in here too.

            if (EnableToolBarFloat)
                li3.Controls.Add(toolBarContainer);
            else if (isDetachableToolBar)
                li3.Controls.Add(toolbar);

            if (DesignMode)
            {
                HtmlGenericControl iframe1 = new HtmlGenericControl("div");
                iframe1.ID = "frame";
                iframe1.Attributes.Add("class", ClassName + "-frame");
                iframe1.Style["width"] = "100%";
                iframe1.Style["height"] = "100%";
                li3.Controls.Add(iframe1);
            }
            _tabList = new HtmlGenericControl("li");
            _tabList.ID = "tabs";
            _tabList.Attributes.Add("class", ClassName + "-tab");
            this.Controls.Add(_tabList);

            _tabContainer = new HtmlGenericControl("div");
            _tabContainer.Attributes.Add("class", ClassName + "-tabcontainer");
            if (TabContainerWidth != Unit.Empty)
                _tabContainer.Style["width"] = TabContainerWidth.ToString();
            _tabContainer.Style["float"] = (Direction == Dir.LTR) ? "left" : "right";
            _tabList.Controls.Add(_tabContainer);

            if (DesignMode && IconsMode == IconType.Icons)
            {
                _tabList.Style["width"] = "100%";

                if (!string.IsNullOrEmpty(TabLeftBorderImage))
                {
                    string leftBorderImage = CreatePath(
                        string.Format(TabsImageSkinFolder, SelectedSkin, TabLeftBorderImage));

                    HtmlGenericControl b1 = new HtmlGenericControl("b");
                    b1.Attributes.Add("class", this.ClassName + "-tableftedge");
                    b1.Style["background-image"] = string.Format("url( \"{0}\" )", leftBorderImage);
                    b1.Style["background-repeat"] = "no-repeat";
                    b1.Style["background-position"] = "left center";
                    b1.Style["border-style"] = "none";
                    b1.InnerHtml = "&nbsp;";
                    b1.Style["float"] = "left";

                    if (IconsMode == IconType.Icons)
                        b1.Style["float"] = "left";
                    else
                        b1.Style["float"] = (Direction == Dir.LTR) ? "left" : "right";

                    _tabContainer.Controls.Add(b1);
                }
                foreach (TabItem ti in Tabs)
                {
                    CreateTabIcons(ti, _tabContainer);
                }
            }
        }

        private DictionaryItem CreateNewDictionaryItemWidthDefaults(DataRow dr)
        {
            DictionaryItem di = new DictionaryItem();
            di.Text = Helper.GetStringProperty("Text", dr);
            di.Value = Helper.GetStringProperty("Value", dr);
            di.Selected = Convert.ToBoolean(Helper.GetStringProperty("Selected", dr));
            di.Defaults = true;
            return di;
        }

        private ToolBarSet CreateNewToolBarSetWithDefaults(DataRow dr)
        {
            ToolBarSet tbs = new ToolBarSet();
            if (IconsMode == IconType.Icons)
            {
                string leftBorderImage = Helper.GetStringProperty("LeftBorderImage", dr);
                string optionsImage = Helper.GetStringProperty("ToolBarOptionsImage", dr);

                if (leftBorderImage != string.Empty)
                    tbs.LeftBorderImage = leftBorderImage;

                if (optionsImage != string.Empty)
                    tbs.OptionsImage = optionsImage;
            }
            tbs.Defaults = true;
            return tbs;
        }

        private ToolBarItem CreateNewToolBarWithDefaults(DataRow dr)
        {
            ToolBarItem tbi = new ToolBarItem();
            int marginLeft = 0;
            int.TryParse(Helper.GetStringProperty("MarginLeft", dr), out marginLeft);
            tbi.MarginLeft = marginLeft;
            tbi.Name = Helper.GetStringProperty("Command", dr);
            tbi.ToolTip = GetLocalizedText(tbi.Name);
            tbi.Enabled = Helper.GetBooleanProperty("Enabled", dr);
            tbi.GroupName = Helper.GetStringProperty("GroupName", dr);
            tbi.ToggleEnabled = Helper.GetBooleanProperty("ToggleEnabled", dr);
            if (IconsMode == IconType.Icons)
            {
                tbi.Break = Helper.GetBooleanProperty("Break", dr);
                string icon = Helper.GetStringProperty("Icon", dr);
                if (icon != string.Empty)
                    tbi.Icon = icon;
            }
            tbi.Defaults = true;
            return tbi;
        }

        string CreatePath(string path)
        {
            if (string.IsNullOrEmpty(path)) return string.Empty;

            path = Helper.GetBackgroundImageUrl(this, path);
            if (string.IsNullOrEmpty(path)) return string.Empty;
            if (IsCustomSkin)
            {
                //now we can map
                path = Helper.MapPath(Host, path, PathType.Relative);
                if (!string.IsNullOrEmpty(path))
                    return path.Substring(2);//remove tilde
            }
            return path;
        }

        void CreateTabIcons(TabItem ti, HtmlGenericControl container)
        {
            string iconUrl = string.Empty;
            if (IsCustomSkin || IsEmbeddedResource(ti.Icon))
                iconUrl = CreatePath(
                     string.Format(TabsImageSkinFolder, SelectedSkin, ti.Icon));
            else
                iconUrl = Helper.MapPath(Host, ti.Icon, PathType.Physical);
            HtmlGenericControl a = new HtmlGenericControl("a");
            a.Attributes.Add("href", "#");
            a.Attributes.Add("class", ClassName + "-tabbutton");
            a.Style["text-decoration"] = "none";
            a.Style["background-image"] = string.Format("url( \"{0}\" )", iconUrl);
            a.Style["background-repeat"] = "no-repeat";
            a.Style["background-position"] = "center center";
            a.Style["border-style"] = "none";
            a.Style["width"] = ti.Width.Value.ToString() + "px";
            if (IconsMode == IconType.Icons)
                a.Style["float"] = "left";
            else
                a.Style["float"] = (Direction == Dir.LTR) ? "left" : "right";
            a.InnerHtml = "&nbsp;";
            container.Controls.Add(a);
            if (ti.Break)
            {
                string dividerImageUrl = CreatePath(
                  string.Format(RootImageSkinFolder, SelectedSkin, ToolBarSeparatorImage));
                HtmlGenericControl b3 = new HtmlGenericControl("b");
                b3.Attributes.Add("class", this.ClassName + "-tabbuttonseparator");
                b3.Style["width"] = "2px";
                b3.Style["background-image"] = string.Format("url( \"{0}\" )", dividerImageUrl);
                b3.Style["background-repeat"] = "no-repeat";
                b3.Style["background-position"] = "center center";
                b3.Style["border-style"] = "none";
                if (IconsMode == IconType.Icons)
                    b3.Style["float"] = "left";
                else
                    b3.Style["float"] = (Direction == Dir.LTR) ? "left" : "right";
                container.Controls.Add(b3);
            }
        }

        void CreateToolBarIcons(string leftBorderImage, string optionsImage, ToolBarSet tbs, HtmlGenericControl container)
        {
            if (!string.IsNullOrEmpty(leftBorderImage))
            {
                HtmlGenericControl b1 = new HtmlGenericControl("b");
                b1.Attributes.Add("class", this.ClassName + "-toolbarsetleftedge");
                b1.Style["background-image"] = string.Format("url( \"{0}\" )", leftBorderImage);
                b1.Style["background-repeat"] = "no-repeat";
                b1.Style["background-position"] = "left center";
                b1.Style["border-style"] = "none";
                container.Controls.Add(b1);
            }
            for (int num2 = 0; num2 < tbs.Items.Count; num2++)
            {
                ToolBarItem tbi = (ToolBarItem)tbs.Items[num2];
                //ToolBar items have a namespace prefixed,
                //eg : bar2.toolBar-save.gif <-- note bar2,
                //since we are required to prefix the bar name
                //with the toolBar item, we need to
                //re-ensure the path and correct this
                //thus : Helper.EnsurePhysicalPath(..)
                string iconUrl = string.Empty;
                if (IsCustomSkin || IsEmbeddedResource(tbi.Icon))
                    iconUrl = CreatePath(string.Format(ToolBarsImageSkinFolder, SelectedSkin, tbi.Icon));
                else
                    iconUrl = Helper.MapPath(Host, tbi.Icon, PathType.Physical);

                HtmlGenericControl a = new HtmlGenericControl("a");
                a.Attributes.Add("href", "#");
                a.Attributes.Add("class", ClassName + "-toolbarbutton");
                a.Style["text-decoration"] = "none";
                a.Style["background-image"] = string.Format("url( \"{0}\" )", iconUrl);
                a.Style["background-repeat"] = "no-repeat";
                a.Style["background-position"] = "center center";
                a.Style["border-style"] = "none";
                a.InnerHtml = "&nbsp;";
                container.Controls.Add(a);
                if (tbi.Break)
                {
                    string dividerImageUrl = string.Empty;
                    if (!string.IsNullOrEmpty(ToolBarSeparatorImage))
                    {
                        if (IsCustomSkin || IsEmbeddedResource(ToolBarSeparatorImage))
                            dividerImageUrl = CreatePath(string.Format(ToolBarSetImageSkinFolder, SelectedSkin, ToolBarSeparatorImage));
                        else
                            dividerImageUrl = Helper.MapPath(Host, ToolBarSeparatorImage, PathType.Physical);
                    }
                    HtmlGenericControl b3 = new HtmlGenericControl("b");
                    b3.Attributes.Add("class", this.ClassName + "-toolbarbuttonseparator");
                    b3.Style["background-image"] = string.Format("url( \"{0}\" )", dividerImageUrl);
                    b3.Style["background-repeat"] = "no-repeat";
                    b3.Style["background-position"] = "center center";
                    b3.Style["border-style"] = "none";
                    b3.InnerHtml = "&nbsp;";
                    b3.Style["float"] = "left";
                    container.Controls.Add(b3);
                }
            }
            if (!string.IsNullOrEmpty(tbs.OptionsName))
            {
                HtmlGenericControl options = new HtmlGenericControl("a");
                options.Attributes.Add("class", this.ClassName + "-toolbarsetoptions");
                options.Style["background-image"] = string.Format("url( \"{0}\" )", optionsImage);
                options.Style["background-repeat"] = "no-repeat";
                options.Style["background-position"] = "right center";
                options.Style["border-style"] = "none";
                options.InnerHtml = "&nbsp;";
                options.Style["float"] = "left";
                container.Controls.Add(options);
            }
        }

        void CreateUpdatePanelProgress(HtmlGenericControl container)
        {
            EmbeddedUpdatePanelProgress.ID = "updatepanelprogress";

            EmbeddedUpdatePanelProgress.AttachToUpdatePanelEventHandlers = false;
            EmbeddedUpdatePanelProgress.EnableDesignView = false;

            if (Skin != SkinNames.Classic && EmbeddedUpdatePanelProgress.Skin == SkinNames.Classic)
                EmbeddedUpdatePanelProgress.Skin = Skin;

            if (!string.IsNullOrEmpty(CustomSkinFolder) && string.IsNullOrEmpty(EmbeddedUpdatePanelProgress.CustomSkinFolder))
                EmbeddedUpdatePanelProgress.CustomSkinFolder = CustomSkinFolder;

            if (CustomSkin != "None" && EmbeddedUpdatePanelProgress.CustomSkin == "None")
                EmbeddedUpdatePanelProgress.CustomSkin = CustomSkin;

            if (!string.IsNullOrEmpty(ExternalStyleSheet) ||
               !string.IsNullOrEmpty(EmbeddedUpdatePanelProgress.ExternalStyleSheet))
                EmbeddedUpdatePanelProgress.RegisterCSS = false;

            container.Controls.Add(EmbeddedUpdatePanelProgress);
        }

        void EnsureDefaultClassIdentifier()
        {
            if (DesignMode) return;
            List<string> temp = new List<string>(CssClassIdentifiers);
            if (!temp.Contains(CssClass))
                temp.Add(CssClass);
            CssClassIdentifiers = temp.ToArray();
        }

        private string GetASPXSyntaxHighlight(string source, bool enableLineNumbering)
        {
            SyntaxHighlighter s = new SyntaxHighlighter("ASPX", new HtmlParser(), enableLineNumbering, source);
            string codeBlock =
            @"<div class=""syntaxhighlighter"">
            {0}
            <br style=""clear:both"" />
            </div>";
            return string.Format(codeBlock, s.GetParsedSourceCode());
        }

        List<string> GetSpellingSuggetions(string word)
        {
            NetSpellDictionary nsd = new NetSpellDictionary(string.Empty, ClientID, ClassName);
            return nsd.GetSuggestions(GetDictionaryFile(), word);
        }

        bool IsEmbeddedResource(string resourceName)
        {
            if (!string.IsNullOrEmpty(resourceName))
            {
                string manifestName = Helper.GetManifestResourceName(resourceName,
                            ManifestResourceNamesCache);
                return (!string.IsNullOrEmpty(manifestName));
            }
            return false;
        }

        void nsd_SpellCheckComplete(object sender, SpellCheckCompleteEventArgs e)
        {
            _webResponseData = e.Result;
        }

        private string PrettyPrintXhtml(string xhtml)
        {
            XmlTextReader reader = new XmlTextReader(new StringReader(xhtml));
            reader.MoveToContent();
            string returnValue = string.Empty;
            using (StringWriter sw = new StringWriter())
            {
                using (XmlTextWriter w = new XmlTextWriter(sw))
                {
                    w.Formatting = Formatting.Indented;
                    reader.WhitespaceHandling = WhitespaceHandling.None;
                    w.WriteNode(reader, true);
                }
                returnValue = sw.ToString();
            }
            reader.Close();
            return returnValue;
        }

        private void RaiseCallbackEvent()
        {
            if (string.IsNullOrEmpty(CallbackArgument))
                return;
            switch (CallbackArgument)
            {
                case "TableDesignerRequest":
                    OnTableDesignerRequest(EventArgs.Empty);
                    break;
                case "CellsDesignerRequest":
                    OnCellsDesignerRequest(EventArgs.Empty);
                    break;
                case "HyperlinkRequest":
                    OnHyperlinkRequest(EventArgs.Empty);
                    break;
                case "CodeHighlighterRequest":
                    OnCodeHighlighterRequest(EventArgs.Empty);
                    break;
                case "WordPasteCleanupRequest":
                    OnWordPasteCleanupRequest(EventArgs.Empty);
                    break;
                case "SpellCheckerRequest":
                    OnSpellCheckerRequest(EventArgs.Empty);
                    break;
                case "SelectedDictionary":
                    TextLoadPostData(this.UniqueID + "$editortext", Context.Request.Form);
                    SelectedDictionaryLoadPostData(UniqueID + "$dictionaryselection", Context.Request.Form, true);
                    DisplaySpellingCompleteMessageLoadPostData(UniqueID + "$displayspellingcompletemessage", Context.Request.Form);
                    IgnoredWordsLoadPostData(UniqueID + "$ignorewords", Context.Request.Form);
                    SpellCheck();
                    break;
                case "WordSuggestionRequest":
                    SelectedDictionaryLoadPostData(UniqueID + "$dictionaryselection", Context.Request.Form, false);
                    WordForSuggestionLoadPostData(UniqueID + "$wordforsuggestion", Context.Request.Form);
                    OnWordSuggestionRequest(EventArgs.Empty);
                    break;
                case "CodeHighlighting":
                    CodeHilighterLoadPostData(UniqueID + "$codehilighting", Context.Request.Form);
                    OnCodeHighlighting(EventArgs.Empty);
                    break;
                case "ValidationRequest":
                case "DesignViewValidationRequest":
                    ValidationRequestLoadPostData(UniqueID + "$htmlview", Context.Request.Form);
                    OnValidationRequest(EventArgs.Empty);
                    break;
                case "HtmlViewHighlightRequest":
                    ValidationRequestLoadPostData(UniqueID + "$htmlview", Context.Request.Form);
                    OnHtmlViewHighlightRequest(EventArgs.Empty);
                    break;
                case "WordPastingCleanup":
                    WordPastingCleanupLoadPostData(UniqueID + "$wordcleanup", Context.Request.Form);
                    OnWordPastingCleanup(EventArgs.Empty);
                    break;
                case "CssClassNamesListRequest":
                    OnClassNameListRequest(EventArgs.Empty);
                    break;
                case "Save":
                    TextLoadPostData(this.UniqueID + "$editortext", Context.Request.Form);
                    TextSavingEventArgs args = new TextSavingEventArgs(Text);
                    OnSaveClick(args);
                    break;
                case "MultiFileUploaderRequest":
                    OnMultiFileUploaderRequest(new EventArgs());
                    break;
                case "FileBrowserRequest":
                    _enumerateFileGallery = true;
                    break;
                case "FileUploadRequest":
                    OnFileUploadRequest(new EventArgs());
                    break;
            }
        }

        void RaiseMultiFileUploaded()
        {
            string argument = Context.Request.Form[Page.postEventArgumentID];
            List<FileTransmitInfo> ftiList = FromJson<List<FileTransmitInfo>>(argument);
            if (ftiList != null && ftiList.Count > 0)
            {
                UploadedMultiFileEventArgs args = new UploadedMultiFileEventArgs();
                foreach (FileTransmitInfo fti in ftiList)
                {
                    HttpPostedFileItem item =
                        new HttpPostedFileItem(fti.Id, fti.ClientSidePath, Context.Request.Files[fti.Id]);
                    args.PostedMultiFile.Add(item);
                }
                OnMultiFilesUploaded(args);
            }
        }

        void RegisterOnSubmit()
        {
            if (DesignMode) return;
            Type csType = typeof(Editor);
            String csName = this.ClientID;
            // Check to see if the OnSubmit statement is already registered.
            string csText = string.Format(
            @"var {0} = $find('{1}');
            if ({0}!=null)
                {0}._prepareForPostback();", this.ID, this.ClientID);
            ScriptManager.RegisterOnSubmitStatement(base.Page, csType, csName, csText);
        }

        private void ResetDictionarySelection()
        {
            foreach (DictionaryItem di in Dictionaries)
                if (di.Selected)
                    di.Selected = false;
        }

        private void SelectDictionaryByValue(string value)
        {
            ResetDictionarySelection();
            foreach (DictionaryItem di in Dictionaries)
            {
                if (di.Value.Equals(value, StringComparison.OrdinalIgnoreCase))
                {
                    di.Selected = true;
                    break;
                }
            }
        }

        private bool SelectedDictionaryLoadPostData(string postDataKey, NameValueCollection postCollection, bool isSuggestionRequest)
        {
            DictionaryItem di = SelectedDictionaryFile;
            string presentValue = di == null ? string.Empty : di.Value;
            String postedValue = postCollection[postDataKey];
            if (string.IsNullOrEmpty(postedValue))
                return false;
            if (!presentValue.Equals(postedValue, StringComparison.Ordinal))
            {
                this.SelectDictionaryByValue(postedValue);
                if (!isSuggestionRequest)
                    OnSelectedDictionary(EventArgs.Empty);
                return true;
            }
            return false;
        }

        private void SetCssClassNamesList()
        {
            if (this.CssClassNamesList.Count > 0) return;
            string fileName = string.Format(
                RootSkinFolder, SelectedSkin, "Preconfig.cssclassnameslist.xml");

            using (DataSet ds = GetTemplateFromResource(fileName))
            {
                if (ds == null) return;
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    CssClassName ccn = new CssClassName();
                    ccn.ClassName = Helper.GetStringProperty("ClassName", dr);
                    ccn.ToolTip = Helper.GetStringProperty("ToolTip", dr);
                    ccn.Value = Helper.GetStringProperty("Value", dr);
                    ccn.Defaults = true;
                    CssClassNamesList.Add(ccn);
                }
            }
        }

        private void SetDictionaryDefaults()
        {
            if (Dictionaries.Count > 0)
                return;
            using (DataSet ds = new DataSet())
            {
                ds.ReadXml(typeof(Editor).Assembly.GetManifestResourceStream(
                    Helper.GetManifestResourceName("Dictionary.defaults.xml",
                    ManifestResourceNamesCache)));
                // Create DataRelation.
                if (ds.Tables.Count > 0)
                {
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        Dictionaries.Add(CreateNewDictionaryItemWidthDefaults(dr));
                    }
                }
            }
        }

        private void SetTabDefaults()
        {
            if (this.Tabs.Count > 0) return;
            string templateName = (ToolBarMode == ToolBarType.Basic) ?
            string.Format(RootSkinFolder, SelectedSkin, "Preconfig.tabsdefaultsbasic.xml") :
            string.Format(RootSkinFolder, SelectedSkin, "Preconfig.tabsdefaultsadvanced.xml");

            using (DataSet ds = GetTemplateFromResource(templateName))
            {
                if (ds == null) return;
                DataRow tabRow = ds.Tables[0].Rows[0];
                string containerWidth = Helper.GetStringProperty("Width", tabRow);
                if (!string.IsNullOrEmpty(containerWidth))
                    TabContainerWidth = Unit.Parse(containerWidth);
                foreach (DataRow dr in ds.Tables[1].Rows)
                {
                    TabItem ti = new TabItem();
                    int marginLeft = 0;
                    int.TryParse(Helper.GetStringProperty("MarginLeft", dr), out marginLeft);
                    ti.MarginLeft = marginLeft;
                    ti.Command = Helper.GetStringProperty("Command", dr);
                    ti.ToolTip = GetLocalizedText(ti.Command);
                    ti.Width = Unit.Parse(Helper.GetStringProperty("Width", dr));
                    ti.Enabled = Helper.GetBooleanProperty("Enabled", dr);
                    if (IconsMode == IconType.Icons)
                    {
                        ti.Break = Helper.GetBooleanProperty("Break", dr);
                        string icon = Helper.GetStringProperty("Icon", dr);
                        if (icon != string.Empty)
                            ti.Icon = icon;
                    }
                    ti.Defaults = true;
                    this.Tabs.Add(ti);
                }
                if (IconsMode == IconType.Icons)
                {
                    string leftBorderImage = Helper.GetStringProperty("LeftBorderImage", tabRow);
                    if (leftBorderImage != string.Empty)
                    {
                        _defaultItems.Add("TabLeftBorderImage", leftBorderImage);
                        TabLeftBorderImage = leftBorderImage;
                    }
                }
            }
        }

        private void SetToolBarDefaults()
        {
            if (this.ToolBars.Count > 0) return;
            string templateName = (ToolBarMode == ToolBarType.Basic) ?
            string.Format(RootSkinFolder, SelectedSkin, "Preconfig.toolBardefaultsbasic.xml") :
            string.Format(RootSkinFolder, SelectedSkin, "Preconfig.toolBardefaultsadvanced.xml");

            using (DataSet ds = GetTemplateFromResource(templateName))
            {
                if (ds == null) return;
                DataRow settings = ds.Tables[0].Rows[0];
                string width = Helper.GetStringProperty("width", settings);
                string height = Helper.GetStringProperty("height", settings);

                if (!string.IsNullOrEmpty(width) && Width == Unit.Empty)
                    Width = Unit.Parse(width);
                if (!string.IsNullOrEmpty(height) && Height == Unit.Empty)
                    Height = Unit.Parse(height);

                DataColumn parentColumn = ds.Tables[2].Columns["id"];
                DataColumn childColumn = ds.Tables[3].Columns["id"];
                // Create DataRelation.
                DataRelation relToolBarItem = new DataRelation("ToolBarSetKey1", parentColumn, childColumn);
                // Add the relation to the DataSet.
                ds.Relations.Add(relToolBarItem);
                foreach (DataRow dr1 in ds.Tables[2].Rows)
                {
                    DataRow[] dr2 = dr1.GetChildRows("ToolBarSetKey1");
                    ToolBarSet tbs = CreateNewToolBarSetWithDefaults(dr1);
                    foreach (DataRow dr3 in dr2)
                    {
                        ToolBarItem tbi = CreateNewToolBarWithDefaults(dr3);
                        bool add = true;
                        if ((!EnableSaveButton && tbi.Name.Equals("save",
                            StringComparison.OrdinalIgnoreCase)) ||
                            (CssClassNamesList.Count == 0 && tbi.Name.Equals("csslist",
                            StringComparison.OrdinalIgnoreCase)))
                        {
                            if (IconsMode == IconType.ImageSprites)
                                tbi.Enabled = false;
                            else
                                add = false;
                        }
                        if (add)
                            tbs.Items.Add(tbi);
                    }
                    tbs.Defaults = true;
                    this.ToolBars.Add(tbs);
                }
            }
        }

        void SpellCheck()
        {
            string templateName = string.Format(RootTemplateSkinFolder,
            SelectedSkin, "SpellCheckerCompleteMessage.html");
            string spellingCompleteMessage = string.Empty;
            if (DisplaySpellingCompleteMessage)
                spellingCompleteMessage = this.GetTemplateData(templateName);

            NetSpellDictionary nsd = new NetSpellDictionary(spellingCompleteMessage, ClientID, ClassName);
            nsd.IgnoredWords = IgnoredWords;
            nsd.SpellCheckComplete += new SpellCheckCompleteEventHandler(nsd_SpellCheckComplete);
            nsd.SpellCheck(GetDictionaryFile(), Text);
        }

        string StripMarkup(string html)
        {
            HtmlStripper b = new HtmlStripper(StripMode.TagOnly);
            html = b.Parse(html.ToCharArray());
            return html;
        }

        string StripUnallowedHtml(string html)
        {
            HtmlStripper b = new HtmlStripper(ElementsAllowed, HtmlStripMode);
            html = b.Parse(html.ToCharArray());
            return html;
        }

        #endregion Methods
    }
}